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

Error message

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls in remember_me_form_alter() (line 78 of /var/www/siegetheday.org/sites/all/modules/contrib/remember_me/remember_me.module).

Non-party guard

In the DSLoA XP expansion, the Hassat "Tareese" was a non-party member who still guarded the strongest character of the main party. You could heal and resurrect him, but not give him armor or weapons.

I'd like to do the same with Grendeline the goblinette and I've tried modifying the flick used for the lost guards at Winstone fortress, subsituting guard for follow, and not making her invincible. The problem is that if she becomes unconscious, she stops guarding and thus following.

Has anyone else done anything like this in DS2? Can you add skrit to a template like DS1, or just flick (and call the skrit from there)? I'm assuming that a modification of hassat_guardian.skrit will still work.

(Edit: I just discovered by making her invincible that the same problem happens when the Player character is knocked out)

You might want to ask Monsoon at the Abstraction site. That was the code used for the 2 side quests in it. I dont think he has done any modding on DS2 though as he doesnt really care for it, but he probably would have a good idea on how to do it.

2 Side quests?

I need to play Abstraction again, as I only remember Denaisia (though she did move around a bit)

[edit: I just realised that the skellies must be using the same thing, but they're not exactly side-quest]

The little girl in the Sea Elf town, but now that I think about it, it was changed from a side quest to a necessary quest. But it does use the same codes.

After a (large) number of iterations with variants of the guardian skrit, invincibility etc. I've hit the show-stopper. Unless I make Grendeline a party member, she can't go through any teleport, and she doesn't survive a restart of the game (which is in effect a teleport back to town). If I want to be able to resume a game after saving and exiting she'll have to become a party member.

Since I don't want to have to make armor meshes, she's going to have to become a modified pet. So now I have to work on a pet UI without the development tab. Grendeline with an inventory is actually a nice benefit, as she can carry surplus loot, while I work on the two-page backpack. I don't know if she'll be invincible, but do minimal damage, or if I need to have her level up and join in the fights on a fair footing. As a pet, she'll not survive on her own, but she'll respawn with the party, so it may not be an important choice, except for balance issues when she joins/leaves.
My intent is that she will automatically leave the party at the end of the quest she's used in, but that could change.

Abstraction site
Dungeon Raider

Since making Grendy a pet, I now have a problem with the conversation that results in her joining the party. It repeats itself from the beginning after adding her to the party.

The flick that issues the StartConversation does not process the lines after it until I cancel the conversation, so I know from that the loop is in the conversation itself. It appears to be related to not having the "view stats" choice (a pet's stats are meaningless before it joins, so I left it out)

Has anyone else been here and fixed anything?

Abstraction site
Dungeon Raider

Sharkull's picture

It seems as though there is a naming standard to recruitable NPC conversations, so that may be it. While I haven't played with this stuff for a while, I think the conversation called from the flick should be named "conversation_grendy_join" (where grendy is the NPC's template name)... looking something like this:

[conversation_grendy_join]
{
[text*]
{
choice = potential_member;
screen_text = "It looks like you might need a companion on the road ahead. Why don't we join forces?";
[choices]
{
[choice_1]
{
reply = accept_member;
screen_text = "That sounds like a good idea.";
}
[choice_2]
{
reply = decline_member;
screen_text = "Not right now, thank you.";
}
}
}
}

And then you need something like this:

[conversation_grendy_accept]
{
[text*]
{
screen_text = "What a team we'll make!";
}
}

Hope this helps... Smile

I think you've hit it. She does not have an acceptance speech, so it's probably picking the first available conversation to use instead.

The name of the initiating conversation doesn't matter (see taar for example), but the _accept one must be there (and defined for the actor in the actors.gas for the region). I'd better give her a _reject or _decline (whichever it needs) as well.

Thanks!

(edited after some further tests)
Well, I certainly had that part wrong, but I still haven't fixed the "loop". The conversation that restarts is the one that has the choice of join/reject in it, which is not the first available any more, neither in the conversations.gas file, nor in the list in actor.gas. I have given her all the possible conversations for rejoin/disband etc. and still no change. I'm now betting on a pet/npc difference and searching the template tree for differences that might account for this.

(Many tests later)
The issue here does seem to be that the last used conversation is being selected instead of the _accept one.

The relevent portion 0f job_talk_hire.skrit is

StringTool.assignf( conversation$, "conversation_%s_accept", templateName$ );
m_Go$.GetConversation.RSSelectConversation( conversation$ );

which confirms that the conversation names are really based off the template name.
In the actor.gas I have

[t:grendeline,n:0xfdb00004]
{
	[conversation]
	{
		talk_flick = grendeline_talk;
		[conversations]
		{
			* = conversation_grendeline_accept;
			* = conversation_grendeline_disband;
			* = conversation_grendeline_disband_rejoin;
			* = conversation_grendeline_reject;
			* = conversation_grendeline_rejoin;
			* = grendeline_base;
			* = grendeline_greet;
			* = grendeline_grumble;
		}
	}
	[placement]
	{
	  q orientation = 0,0.866025,0,0.5;
	  p position = -1.98719,0,-0.86058,0xc3208373;
	}
}

As you can see, the template name matches the right part of the conversation name.

To play safe I've pasted the names over the ones in conversations.gas to make sure they match. But every time, I get the conversation repeated, instead of "conversation_grendeline_accept" being started.

I've checked every space against working examples (see the pet shop problem over at the Forge for what an extra space can do!) but still I can't see it. AAAAARGHHHHH!

Abstraction site
Dungeon Raider

Sharkull's picture

[t:grendeline,n:0xfdb00004]
{
	[conversation]
	{
		talk_flick = grendeline_talk;
		[conversations]
		{
			* = conversation_grendeline_accept;
			* = conversation_grendeline_disband;
			* = conversation_grendeline_disband_rejoin;
			* = conversation_grendeline_reject;
			* = conversation_grendeline_rejoin;
			* = grendeline_base;
			* = grendeline_greet;
			* = grendeline_grumble;
		}
	}
	[placement]
	{
	  q orientation = 0,0.866025,0,0.5;
	  p position = -1.98719,0,-0.86058,0xc3208373;
	}
}

Where's the line for
* = conversation_grendeline_join;
(I'm not sure if this is one of the enforced names, but I used it for my_test_world). :?

Also, is there any logic in your talk flick that might be circular?

the _join is not a required name. job_talk_hire is the one that builds the names, and that doesn't get run until after the hire event. Taar doesn't have a _join conversation either, and she works. I've refered to Taar mostly because she matches the scenario I'm using, there's a normal conversation that ends up with an offer to join the party.

The talk flick is non-circular. I've also replaced the StartConversation line in it with two and split the conversation itself (creating the second part as .._join just be really sure) to match. Only the last one gets restarted, and they both would if the loop was in the flick.

The conversations work by a combo of two calls, one to add the conversation to the list - RSSelectConversation - and another to play it. It's behaving as if this one never gets flushed from the list, so it stays on top and gets restarted. My next test will be to try and add an explicit removal somehere appropriate in the skrit/flick code.

This will probably end up being fixed by something apparently totally unconnected with conversations. I was having the same sort of problem with a useable object not triggering a flick that was fixed by adding a use-point.

Abstraction site
Dungeon Raider

I accidentally have seen this:

ghastley wrote:
Since making Grendy a pet, ...

To summarize it: You have talking NPC in shape of a pet, and now it should join the party under some circumstances, right!?

I'm just asking this to be sure, i hade some real nightmares joining my pet(s) to a party...

I need her to be incapable of equipping anything, or else I need to build a lot of extra meshes, so a pet is the only party member option. If you have any specific experience to share...

Abstraction site
Dungeon Raider

I just have noticed strange things when adding a pet with default hire functions of DS2,
it has removed/erased all chars stored in the inn - but 'amazingly' only in multiplayer:
http://66.225.220.102/forums/index.php?showtopic=11010
There would be also a summary of these sad experiences in the GPG-Forum, but anyhow
the forum there is down right now...

However after some weeks I have found a solution by making two pets:
One is the real pet unable to speak (as all the other default pets), the other was some
kind of speaking 'pseudo quest pet' (a speaking monster looking as a pet) just made to
initiate the joining of the real pet. And a custom flick function (crrently used in the War
Hound pet mod) did the exchange of these two actors if needed - so the player gets a pet
made by of template with rather normal structure, no hirable stuff mentioned at all.

Nethertheless joining pets seems to be much more critical and riskful, so i'm not sure
if such a solution will match for your belongs too.

.

---Edit: I just had some time to look closer the that matter.
Here some ideas to be a bit more constructive hopefully:

1) There is just a flick command 'Guard' for garding other roles for a cerval duartion.
Maybe this is just enough for the belongs here!?
However this may fail after/during a battle.

.

2) About adding a pet:


	event a2_war_hound_will_join;

	thread main
	{
	    speaker:		// speaker IS A SPEAKING NON-PET ('PSEUDO-QUEST-PET') NPC/MONSTER, BUT EXACLY LOOKING AS THE REAL PET IN BABY STAGE
		Capture;

		// ...
		//
		// INTRO/QUEST/GENERAL CONVERSATION CODE...
		// ...


		// THE PARTY HERO WANT US TO JOIN THE PET:

		ClearCue a2_war_hound_will_join;

		if WhenReplaceAndJoinParty( speaker, listener, "pet_war_hound", "", true ) 	// THIS WILL ADD THE REAL PET
		{
			sleep, duration 0.4;		// JUST ABOUT HALF A SECOND OVERHEAD
			DrawExclamation false;
			Hide;				// WE HIDE BUT NOT DELETE THE PSEUDO-QUEST-PET YET, WE MUST MAINTAIN IT FOR OURTO-CONVERSATION!
			Cue a2_war_hound_will_join;
			startConversation conversation_pet_war_hound_hire_accept, wait ; // WORKAROUND, SINCE WE ADD THE PET 'MANUALLY' THIS CONV NO LONGER STARTS AUTOMATICALLY!
		}


		// ...
		//
		// QUEST-OUTRO-CONVERSATION CODE IF REQURIED...
		// ...


		if WhenCue( a2_war_hound_will_join )	// IF WE HAVE THE REAL PET JOINED, THEN REMOVE INVISIBLE PSEUDO-QUEST-PET
		{
		   speaker:
			SetInvincible false;
			Delete true, wait;
		}


	} // MAIN THREAD END


So the core of this flick code is 'WhenReplaceAndJoinParty()' - it's actually a command
tuned as a condition to get returned true or false about the joining process to be able to
act on in suitable manner (eg. 'WhenPartySizeMaxed()' often doesn't work as it looks like).

[t:flick_condition,n:WhenReplaceAndJoinParty]
{
	server_only	= true;
	is_latent		= false;
	can_wait		= false;
	require_this	= true;
	skrit_addr		= world/global/flick/commands/fc_war_hound;	// This is no real condition, it just will return a 'success bool'.
	condition_func	= WhenReplaceAndJoinParty$;
	[args*] { type = role; name = "inActor"; doc = "Actor role (pseudo-joiner) who _by_quest_meaning_ wants to join the party."; }
	[args*] { type = role; name = "inRole"; doc = "Member role representing the party."; }
	[args*] { type = string; name = "inTemplate"; doc = "Template name to replace the actor (pseudo-joiner) in moment of joining."; }
	[args*] { type = string; name = "inName"; default = ""; doc = "Optional screen name for real joiner. If empty inActor's name is taken."; }
	[args*] { type = bool; name = "inKeepActor"; default = false; doc = "If true, pseudo-joiner won't be removed."; }
	[args*] { type = bool; name = "inDevReport"; default = false; doc = "Sends a reports to the screen, for debugging generally."; }
}

Probably that concept is a bit wired, but watching all the matters that generally may
occur about the inn it seemed to be quite secure.
Feel free to use that funtion, it's part of the War Hound mod - personally i just would
be happy if you could use different function and file names supposed you intend to do
any changes on 'flick_function_war_hound.gas' or 'fc_war_hound.skrit'.

.

3): However, for a guarding actor i would try to maintain it as NPC (and not as pet) specially because it won't affect the current party size.
Probalby it's possible to create a skrit component to let this gaurd protect the hero as summons do!?

			GoMind summonedMind$ = summoned_goid$.Go.Mind;
			if( summonedMind$.GetMovementOrders != MO_HOLD && 
				summonedMind$.UnderstandsJob( JAT_GUARD ) && 
				summonedMind$.FrontActionJat != JAT_GUARD &&
				summonedMind$.CanOperateOn( owner.go.parent ) &&
				summoned_goid$.Go.IsInActiveWorldFrustum &&
				owner.go.parent.IsInActiveWorldFrustum )
			{
				Job action$ = summonedMind$.GetFrontJob( JQ_ACTION );
			
				if( action$ != NULL )
				{
					if( action$.JobAbstractType != JAT_FIDGET )
					{
						return;
					}
				}
				report.reportf("summon","summon[0x%08x]: omni - ControlSummon$ - Making sure summoned creature guards!\n", owner.Goid );
				
				summoned_goid$.go.Mind.RSGuard( owner.go.parent.Goid, QP_BACK, AO_COMMAND );
			}


This code is included in a repeating timer in 'spell_summon.skrit' and seems to be the reason why summons protect the hero.
Probalby it's possible to separate and enhance that code so it can be started eg. by an activation message send by the conversation flick file!?
Please make a post if interested in the last way, i will browse my pending work files. Actually i have tried once to make converted War Hound cousins gaurding the party but i haven't found untill now a satisfying solution.

I have browsed my stranded work files meanwhile...

With some minor changes there seems to be a skrit component that probably
could be used as a component for an NPC to guard and follow another actor
under some circumstances (dying, engaged in battles,...), also an activation
by flick could be added.

I will put it online if the original idea is still an option.

The problem I found with "guard" skrits was that the character was not a party member, and so did not participate in transporters, or respawn on death. Those would seriously break the quest, so I need Grendeline to become a party member.

Right now I can just cancel the restarted conversation, and everything appears to work after that, so it's just a question of patiently debugging the conversation sequence until I get the _accept one instead of the repeat.

Abstraction site
Dungeon Raider

Sharkull's picture

The only thing else I can think of is to code the pet to join the party manually instead of using "reply = accept_member" within the conversation. The problem with that is in knowing the command to call within a flick which would do this... :?

Indeed NPCs following by skirt won't 'use' a teleporter, but that's the way teleporters are programmed to work, they only are looking for party members and not for allied NPCs/monsters/summons.

However the matter of dying NPCs would be solved more or less in the menentied guard component.
Although resurrection spells won't work either (same reason as for teleporters) it's often sufficent just to give them some health points back to make them live again.

So if you need 'teleportation inclusive' and don't want to revise the hole teleporation code a pet is probably really the most cofortable way.

Of course there is no flick function for joining the party, so I had to add one. But now I have, and Grendeline joins the party when she's supposed to, without any looping conversations.

Now back to eliminating the skills tab and replacing it with a backpack tab for extra inventory!

Abstraction site
Dungeon Raider