forums | blogs | polls | tutorials | downloads | rules | help

Drianjul_Don't_You_Cry

This mod lets you recruit Drianjul into your party after the second Surgeon is killed and the portal to Solanum is opened. Special thanks go out to KillerGremal and Darkelf for insights and helping me get the coding correct.

Known Issues:

Change Log:
03-24-11 (v3)
• Minor tuning provided by KillerGremal to allow Drianjul to have pm_starting_gear for veteran and elite mode.
• New MP3 and WAV files added for Drianjul’s banter and death.

03-21-11 (v2)
• Drianjul could attack but could not be attacked. Had to adjust template to allow her to take damage again.

03-21-11 (v1)
• Autojoiner is obsolete, Drianjul now joins party the regular way.

Author: Volkan (aka PhoeniX)

Tank Priority = 1000
Mod Version Number: v3
Release Date: March 24, 2011
Mod Size (approx.): 250 KB
Contact Information:

Download Link
Drianjul Don't You Cry YouTube Video

blogs: 

Comments

Made the mod and recruited Drianjul on Mercenary setting. Played through Utraean Peninsula, DOA, and back through DS2 and BW on Veteren settings, Utraean Peninsula and DOA again with no problems. Party is now level 135 going through DS2 Elite finally. Got several d/c yesterday but thought it might be graphic card "hiccups". Started playing again today and get this bit of fun.

Drianjul is leaving party frustum (not sure if that applies, but it is the only way I can describe it) and just freezes in place. She returns to party when I select her, but there is definately some deeper issues that may affect gameplay. Sad

Concerning Drianjul's template in Drianjul_Don't_You_Cry.ds2res, most propably [cmd_change_property_owner] will cause troubles. This component is only for instances with a valid/steady scid, like quest NPCs placed in SE2 (but not for party members in/from a savegame).

So for test purpose, remove [cmd_change_property_owner] once. Also [mind] should be revised/adjused, better take here the 'finala' template as reference, not 'drevin'. In this context, [npc_use_power] is widely useless - the required event to trigger this hardly ever will arrive.

I readjusted Drianjul's template and it seems to be ok so far. Will have to get my party to the Surgeon quest in Broken World to see if what was done breaks the quest now. Am also studying how you changed Keirnan from a quest npc to a hireable character and will try to see if I can get her to join without an "autojoiner" block in the template.

PhoeniX wrote:
. . .
Am also studying how you changed Keirnan from a quest npc to a hireable character and will try to see if I can get her to join without an "autojoiner" block in the template.

That's quite possible. You could replace/update Drianjul's conversation so it's a able to perform the hiring action, also her existing talk flick could be modified for any post-hiring tasks.
You should examine once how Deru will be hired, so maybe start with the actor.gas file of Eirulan. You will find there the names of the required conversations and the flick file.

A minor problem however is the [cmd_change_property_owner] component. If you intend to put all in one mod then you should not remove this component from her template (it's needed for the quest here).
As rough work-around for the moment, just add [cmd_change_property_owner] { } in her template and specify its properties in world/maps/ds2x_world/regions/x2_01_elftown/objects/actor.gas instead:

[t:ds2x_x2_01_drianjul,n:0x20400049]
{
	[cmd_change_property_owner]
	{
		state1_change_visible = true;
		state1_change_selectable = true;
		state1_change_disable_mind = true;
		state2_change_visible = true;
		state2_change_selectable = true;
		state2_change_disable_mind = true;
	}
	[conversation]
	{
		talk_flick = x2_01_drianjul_talk;	// TUNED FOR/AFTER HIRING

		[conversations]
		{
		//	* = drianjul_base;
		// EXPANDED+NEW CONVERSATIONS:
			* = drianjul_base_hire;
			* = conversation_drianjul_accept;
			* = conversation_drianjul_disband;
			* = conversation_drianjul_disband_rejoin;
			* = conversation_drianjul_join;
			* = conversation_drianjul_reject;
			* = conversation_drianjul_rejoin;
		}
	}
	[placement]
	{
	  q orientation = 0,0.991624,0,-0.129156;
	  p position = 0.692402,0.25,1.58563,0x83d7366f;
		use_point_scids = 0x204000AF;
	}
}

The conversations can exist in a separate file (e.g. conversations_drianjul.gas, in the 'conversations' folder).
Drianjul's flick file you should merge/expand with Deru's flick file. That's not much work, currently there's no hiring icon/indicator and you basically just had to replace the conversation name.

im thinking that auto_joiner skrit should be rewrote to be Drianjul specific... as the autojoiner is made for drevin...

//////////////////////////////////////////////////////////////////////////////
//
// File     :  Drianjul_auto_joiner.skrit
// Author	:  DarkElf
//
// Drianjul will automatically join the player's party
// 
// this component has been customized to work exclusively with Drianjul.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// Public definitions

property bool			initial_party_joiner$	= false;

// Reserved tags
property bool   		_server_only$			= true;
property string 		_doc$					= "Component to have characters auto-join when they are created.";

owner											= GoSkritComponent;

string bDrianjulTracker$ = "drianjul_joined_party";

bool AddToScreenParty$( Go member$ )
{
	if ( Server.GetScreenParty() != NULL )
	{	
		report.reportf( "party_joiner","member[0x%08x]: Successfully Added\n", member$ );
		WorldJournal.RSSetSessionBool( bDrianjulTracker$, true ); // remember that Drianjul has joined during this session
		owner.Go.Mind.SEnable();
		owner.Go.Mind.SSetMayAttack( true );
		owner.Go.Mind.SSetMayBeAttacked( true );
		owner.Go.Aspect.SSetIsVisible( true );
		owner.Go.Aspect.IsInvincible = false;
		owner.Go.Aspect.SSetCurrentLife( owner.Go.Aspect.GetMaxLife() );
		Server.GetScreenParty().Party.RSAddMemberNow( member$ );
		return true;
	}	
	return false;
}

startup state Begin$
{
	trigger OnGoHandleMessage$( WE_ENTERED_WORLD )
	{
		#only( game )
		[[
			owner.Go.Aspect.IsInvincible = true;
			owner.Go.Mind.SSetMayAttack( false );
			owner.Go.Mind.SSetMayBeAttacked( false );
			owner.Go.Mind.SDisable( true ); // true = make this actor invisible
	
			if ( initial_party_joiner$ )
			{
				this.CreateFrameTimer( 1, 0 );
			}
			else
			{
				this.CreateTimer( 1, 0.5 );
			}
		]]
	}

	trigger OnTimer$( 1 )
	{
		// Did Drianjul already join the party during this session?
		if ( WorldJournal.GetSessionBool( bDrianjulTracker$ ) )
		{
			// This is not the first Drianjul encountered! We will stay invisible and braindead; ready for next session.
			SetState Finish$;
		}
		// This is the first copy of Drianjul encountered this session, so
		// attempt to join the party
		else if ( !AddToScreenParty$( owner.Go ) )
		{
			this.CreateTimer( 1, 0.5 );
		}
		else
		{
			// we have successfully joined the party
			SetState Finish$;
		}
	}
}

state Finish$
{
}

and then in template use [drianjul_auto_joiner]

@Darkelf: Indeed party_auto_joiner.skrit is not sophisticated enough for regular/flexible use. Otherwise there (hopefully) would be a property for the name of the session bool, also automatically starting as soon as loaded may not be wished, and endlessly looping if joining fails neither (while hidden).
This component really has been tuned for the Drevin in the tutorial only, that's probably also why there is nothing to check the (current) party size limit.

 
 

@PhoeniX: You've got a PM with an example mod. Wink There is still some potential to improve it, however joining happens the 'normal' way without party_auto_joiner.skrit using Deru and Taar as guidelines.
You will also see that i have 'wasted' Shocked Drianjul's template and put it into a separate file (in most case this works very well, makes the mod smaller and won't cause conflicts in case any other mod would contain npc_unsorted_ds2x.gas).

@Darkelf and KillerGremal: Thanks for the suggestions and feedback. Smile

Working at getting her to join after 2nd Surgeon is killed.

[x2_01_drianjul_talk]
{
	external role (actor)	speaker;

    entry main;

    thread main
	if !WhenQuestComplete( x2_p6_surgeon2 )
	{
		speaker:
		Capture;
		StartConversation drianjul_hire_base, wait;
		Release;
	}
	else if WhenQuestActive( x2_p6_surgeon2 )
	{
		speaker:
		Capture;
		StartConversation drianjul_base, wait;
		Release;
	}
}

Would this be sufficient or is more needed? Will be updating the "conversation.gas" to include both versions.

Related on the mod i've sent you, the flick could look like this:

// PATH:
// world\global\flick\sequences\ds2x_world\x2_01_elftown\x2_01_drianjul_talk.flick
////////////////////////////////////
//NPC SCID
// * s:0x20400049
////////////////////////////////////
[x2_01_drianjul_talk]			// MODIFIED/EXPANDED
{
	role (actor) speaker,listener;
//	external role 	hire_icon = 0x00000000;
	
	entry main;

	thread main
	{
	
	   speaker:
		Capture;

		if !WhenQuestComplete( x2_p6_surgeon2 )
		{
			StartConversation drianjul_base, wait;
		}

		else // QUEST x2_p6_surgeon2 HAS BEEN COMPLETED. DRIANJUL OFFERS TO JOIN:
		{
			startConversation conversation_drianjul_join, wait;			

			DrawExclamation false;		// ENABLED IN INSTANCE (INSTEAD OF MISSING HIRE ICON) NOW TURN IT OFF.

			if WhenActorIsPartyMember( speaker) 
			{
				SetInvincible false;

		//		BroadcastMessage (hire_icon, WE_USER_INDICATE_EMITTER_OFF);	
			}
		}

		Release;
	}
}

Instead of 'drianjul_hire_base' only 'conversation_drianjul_join' is used (widely because of job_talk_hire.skrit).
Also 'drianjul_base' is currently not used in the example mod, so you have to put it on Drianjul's conversation list again.

However I doubt that else if WhenQuestActive( x2_p6_surgeon2 ) is really needed, so i've removed it.
You only proceed to the lower part of the flick if the quest 'x2_p6_surgeon2' is done, so all its tasks most probably are completed as well and not active anymore!(?)

 
By the way, perhaps better leave 'conversation.gas' as it is. Supposed your conversations have unique name, you simple could add further files in the conversations folder. Smaller mod, lower risk of mod conflicts.

@KillerGremal: Sent you a pm with link to completed draft. Can you check it for coding errors for me please. Smile

Edit: Running a pre-made party through BW for test purposes. Will take a bit to get to act 3 though.

@KillerGremal

if WhenActorIsPartyMember( speaker) 
			{
				SetInvincible false;

		//		BroadcastMessage (hire_icon, WE_USER_INDICATE_EMITTER_OFF);	
			}
		}

using Yoren as example, may want to add a couple lines -

if WhenActorIsPartyMember( speaker) 
			{
				SetInvincible FALSE;
				SetMayBeAttacked TRUE;
				SetMayAttack TRUE;

		//		BroadcastMessage (hire_icon, WE_USER_INDICATE_EMITTER_OFF);	
			}
		}

@Darkelf: Thanks, Yoren really needs this, Drianjul not (yet) but it would be safer like this indeed. Smile

 

@PhoeniX: If you like to take advantage of Darkelf's input, then add the following in actor.gas for Drianjul:

	[aspect]
	{
		is_invincible = true;
	}
	[mind]
	{
		actor_may_attack = false;
		actor_may_be_attacked = false;
	}
You never know who is intruding Aman'lu (...and some people have fun to blow up quest NPCs just to find a vulnerable quest or feature, you know). Wink
So as long as not hired this will protect her, and reverted again by the flick when hired.

 
However there's something else you should check too in x2_01_drianjul_talk.flick.

		if !WhenQuestComplete( x2_p6_surgeon2 )
		{
			// DRIANJUL MAY JOIN
		}
Condensed this is what your flick currently does. But shouldn't you remove the exclamation mark to match your posted intention?

KillerGremal wrote:
....But shouldn't you remove the exclamation mark to match your posted intention?

I have no idea what the exclamation mark's function is, but have seen its use in other coding. What exactly is the function it provides to the code?

A question mark in front of a command means 'not', so it give the negative/opposite meaning.

Adjustments being made (again). Thank you Darkelf and KillerGremal for your input in helping me get this thing coded correctly. Smile

Edit: Hope the engine recognizes WMA as well as MP3 files so this will work.

[conversation_drianjul_accept]	// AUTOMATICALLY STARTED BY job_talk_hire.skrit IF SUCCESSFULLY HIRED.
{
	[text*]
	{
	//	sample = s_vo_par_116_Taar_030;
	//	screen_text = "Together we will perform good works, .";
		sample = s_vo_ds2x_par_211_Drianjul_accept;
		screen_text = "I am glad you are back, Lyth'airyn would have wanted to be avenged.";
	}
}

And added to the voice_info.gas
[voice_info]
{
	[voice_durations]
	{
		// filename = duration (in seconds)
		s_vo_ds2x_par_211_Drianjul_accept = 5.13;
	}
}

WMA file for Drianjul Accepts/Rejoins.

PhoeniX wrote:
. . .
And added to the voice_info.gas
[voice_info]
{
	[voice_durations]
	{
		// filename = duration (in seconds)
		s_vo_ds2x_par_211_Drianjul_accept = 5.13;
	}
}

WMA file for Drianjul Accepts/Rejoins.

You don't need to list it in voice_info.gas, it also would work without this. However if DS2 generally has WMA support, i have some doubts...
Instead of MP3 you also could use WAV files (PCM) although they can make a mod pretty large.

	[aspect]
	{
		is_invincible = true;
	}
	[mind]
	{
		actor_may_attack = false;
		actor_may_be_attacked = false;
	}

actually i wouldnt even bother putting those in aspect or mind because none of the other mercs use those, accept on the map side and even then monsters dont enter town to fight so would be useless, besides all this can be done in drianjul's flick

Getting ready to enter first Surgeon dungeon now. No monsters attack Amanlu but she is right by the first Surgeon at the beginning.

Edit: So far so good. Made copies of my save games before entering Surgeon dungeon though.

Darkelf wrote:
	[aspect]
	{
		is_invincible = true;
	}
	[mind]
	{
		actor_may_attack = false;
		actor_may_be_attacked = false;
	}

actually i wouldnt even bother putting those in aspect or mind because none of the other mercs use those, accept on the map side . . ., besides all this can be done in drianjul's flick

To prevent misunderstandings, this is for the 'map side' only. And this should not be set/applied in the in the flick, the flick is here (partially) to revert these settings - in case they have been set in the instance before (as e.g. Yoren has).
That's why I wrote actor.gas before, pointing on world\maps\ds2x_world\regions\x2_01_elftown\objects\actor.gas where Drianjul's instance is (her template is in another file).

Usually you would add these settings via the property window in SE2 (assumed you managed it to open a Broken World region). So i guess PheoniX just will to copy+paste to modify the existing actor.gas.
Assumed you would add these settings in the template, you would add most probably a bug, preventing the hired member to interact in battles (since the hiring flick isn't active anymore in later sessions).

 
 
 

Darkelf wrote:
. . .and even then monsters dont enter town to fight . . .
Normally they do not.

But remember some DS1 mods summoning evil monsters. I'm not sure if this exists for DS2, but imaginable.

Also there is a bug/lack to navigate (melee) monsters everywhere:
- Let a melee monster hit you once or twice.
- Left-click on a distant ground position.
As result the monster will walk/follow to that point. And the monster won't stop even if your moving hero cancels his own walk with another left-click.

With some exercise (and scheduling, there's an elevator) it's possible to make Garganturax visit Eirulan: Evil

I'm not sure if developers knew about this lack, but it's probably why invincibility is used (or at least intended to do so) and reverted again in the flick when hired.

PhoeniX wrote:
Getting ready to enter first Surgeon dungeon now. No monsters attack Amanlu but she is right by the first Surgeon at the beginning.

Edit: So far so good. Made copies of my save games before entering Surgeon dungeon though.


-------------

@Phoenix
now i confused, cause the screenshot which is awesome in progress, shows her with her ! above her head but yet u said u made copies before entering the surgeon dungeon, so is the screenshot taken after beating the surgeon?

@KillerGremal, no misunderstandings in fact after further study since she is being converted from npc (which doesnt fight) to hero(who defaults to fighting) what u have suggested would be needed the invincible, not attackable and not being able to attack, especially since this new drianjul is used in the surgeon dungeon as well, and if indeed this template was used in the dungeon then perhaps the surgeon would kill her in her cage assuming that map actor file was changed as well.

@Phoenix - i installed the original alpha file to test it, and i like her, but after she leveled up and all i noticed that while she is a magus, her nature magic prevails after a forced level up and i also notice she has no combat magic spells in inventory, so i was wondering if maybe she could have some combat magic spells added to her inventory??

@Darkelf: Yes that screenshot is after I killed the Surgeon and released Drianjul back to Amanlu. Quest chain is secure, she didn't die at the Surgeon, and she is showing signs that the mod is working as intended (so far anyway). I am making video footage of Drianjul's progress of becoming a hireable party character as it unfolds.

I got the idea of making Drianjul a hireable character after playing Aranna Legacy and realized there was an empty bracket for the dual class Nature/Combat as brought about by the "Rending Aura: Magician" spell (Splits experience gain as Nature 68%/Combat 32%).

I probably should add some combat spells into Drianjul's inventory for those who don't play Aranna Legacy though.

And the level 99 scaling unique chain mail armor set in my BW More Hair v3 are also aimed at the magus class (The regular chain mail armor is either Nature or Combat useable).

The other dual class spells in Aranna Legacy are for Ranged/Nature (68%/32%) and Melee/Combat (68%/32%).
I like the "Rending Aura: Arrow Bane" for multi-arrow fun as well as the extra healing abilities.

@KillerGremal: There are other types of mayhem that can be done to quest npcs that can attack and be attacked also.
Smile

@Darkelf: Well, in Aman'lu template 'ds2x_x2_01_drianjul' is used, in the Surgeon's dungeon it's template 'ds2x_x2_04_drianjul'. So 'ds2x_x2_01_drianjul' easily can be tuned as party member without affecting the fight with the Surgeon, there is only a minor problem with the mentioned [cmd_change_property_owner] component.
There are different approaches then how to tune Drianjul at Aman'lu, however I'm convinced PheoniX will manage it that template/instance/flick/conversation all correctly will work together, so Drianjul will be (more or less) safe when not hired, and that she performs as as party members should when hired once.

 
 

PhoeniX wrote:
. . .
@KillerGremal: There are other types of mayhem that can be done to quest npcs that can attack and be attacked also.
Smile

Hm, actually he should be without consciousness, but not dead. Puzzled I have to recheck this once, specially in v2.3/BW.

By the way, it's a good idea to equip Drianjul with nature and combat spells. At higher level you most probably need spells of different classes anyway due to the increasing monster resistances.

awesome pics... good work PhoeniX! now the question is will there be more hireables in the future? Theres a ghost pirate in the secret area of ds2 that sure would make a good hireable if someone would want to take a stab at it.

as it dont look like DS3 is gonna be moddable i think people will flock back to ds2 and ds1 after they get disappointed.

also make sure to test the disband from inn, in past had issues with disbanding characters especially when it used the auto join, which im glad u found a work around for.

omg there is 2 Drianjul templates, i swear i never saw them b4, why gpg did that is beyond me... lol gosh bw needs more mods... get to work guys lol!

and i have never seen Private Nolan die? is that part of Aranna Legacy? i havent played that since prior to adding of the ghost summons.. perhaps should load it again someday..i always liked the additions made by KillerGremal.

Thank you Darkelf and KillerGremal for your insights and helping me to get things coded correct. I was worried for a minute until I realized that the second Surgeon quest isn't complete until the portal to Solanum is opened. Still need to do some clean-up work to the mod but things work great (except for the WMA file not being recognized, I did't think it would, but I was hoping). Drianjul Don't You Cry ^^ :dance1:

Added veteran and elite armors and spells to template. Should work this way like the pm_starting_gear flick provides.

/*[t:template,n:ds2x_x2_01_drianjul]
{
	Edit 2:  Code removed, didn't work and it was stretching the web page too much.  :) 
}

Edit: Realized on further testing that Drianjul could attack but not be attacked. Tried to set it in .flick but it would not take. Had to set the properties in her template.gas file.

Ususally the merc/vet/elite-depending gear is given in a flick executed by a 'cmd_run_flick' object placed at the position of the actor to hire.
In a GPG-like setup, there is also an 'emitter_indicate' object placed to display a hire icon above the actor.
And often in v2.2 the object 'cmd_change_property' is used to temporarily hide/show actors, if we could use its functionality then Drianjul wouldn't need the critical component [cmd_change_property_owner] (however both works almost the same).

A map maker with/in SE2 most probably would set these 3 objects around/below the actor.
Actually we could add these objects without SE2 too (adding them e.g. in actor.gas and registering them manually in streamer_node_content_index.gas) but there's another (hopefully easier) approach:

Let's take a look on the following row in Drianjul's [placement] (in actor.gas):

		use_point_scids = 0x204000AF;
0x204000AF refers on a 'use_point' (in special.gas of that region). Here it's possible to (ab)use this object, it has no evident purpose and luckily it's on the same place/node too as Drianjul is (has some importance for the flick updating her gear).
Now this useless use-point could be replaced by a custom/combined object that performs all 3 tasks mentioned above:
[t:template,n:cmd_hire_support_drianjul]
{
	specializes   = cmd_const;
	doc           = "auxiliary object to manage hiring, BW map specific";
	extra_doc     = "combined/multi-task object for hiring Drianjul";
	category_name = "flick";
	[cmd_run_flick]
	{
		launch_event = we_req_use;
		flick_name = "give_gear_drianjul_ds2x";
		role_name_1 = "character";
		role_scid_1 = 0x20400049;		// DRIANJUL'S SCID AT AMAN'LU
	}
	[common]
	{
		dev_instance_text = "Trigger to start cmd_run_flick with we_req_use";
		[instance_triggers]		// COPIED FROM DERU, WIDELY THE SAME
		{
			[*]
			{
				action* = send_world_message("we_req_use",0,0,"self","");
			  b can_self_destruct = true;
				condition* = receive_world_message("we_entered_world",0,"on_first_message");
			  f delay = 0.000000;
			  b flip_flop = false;
			  b multi_player = true;
			  b no_save_trig_bits = true;
			  b no_trig_bits = false;
				occupants_group = ;
			  f reset_duration = 0.000000;
			  b single_player = true;
			  b single_shot = true;
			  b start_active = true;
			}
		}
	}
	[cmd_change_property]		// ACTIVATED FROM x2_04_drianjul_talk.flick
	{
		object_list = "0x20400049";		// DRIANJUL'S SCID AT AMAN'LU
		state1_change_visible = true;
		state1_change_selectable = true;
		state1_change_disable_mind = true;
		state2_change_visible = true;
		state2_change_selectable = true;
		state2_change_disable_mind = true;
		state1_visible = true;
		state2_visible = false;
		start_state = 2;
	}
	[indicate_emitter]		// ACTIVATED FROM give_gear_drianjul.flick OR x2_04_drianjul_talk.flick
	{
		height = 2.9;
		scale = 1.05;
		ignore_actor_height = true;
		initial_texture = 5;			// 5 = HIRE ICON 
		initially_active = false;
	}
	[gizmo]		// ...JUST IN CASE THIS TEMPLATE EVER WILL BE USED IN SE2.
	{
		model				=	m_i_glb_SE-niscomm;
		texture				=	;
		diffuse_color		=	0.3, 0.3, 1.0;
		use_diffuse_color	=	true;
	}
}

@PhoeniX: I've tried it out and it works fine (in a short test) but it was necessary to tune/add 5 other files based on your recent files (as far as up to date). The changes are small only, however too much to post all here, so check out your PMs. Wink I'm going to send you an example mod, generally working, but maybe not as tuned as your current state is.

@KillerGremal: Thank you for your time in helping me fine-tune this mod. All changes seem to be working for me as well. V3 is now available for upload. Smile