Aller au contenu

Photo

Area Shout


  • Veuillez vous connecter pour répondre
1 réponse à ce sujet

#1
last_dance

last_dance
  • Members
  • 3 messages
Using the OnChat module event I am attempting to make something like an area shout. The general idea is that a DM could type something in and it would broadcast to the whole area, but only the people in that area. I thought this would be as simple as Using SpeakString or ActionSpeakSctring and inceasin g the volume, but appearently it doesn't work that way.

Does anyone know a way to go about doing this? Here is what I have so far. It seem to be accruately recognizing the command and parsing out the string I want sent, as it send that tot he PC just fine, but the character doesn't actually say it.


int StartingConditional(object oSpeaker, object oTarget, int nChannel, string sChatMessage){
  if (GetIsDM(oSpeaker) || GetIsDMPossessed(oSpeaker)) {
    if (FindSubString(sChatMessage, "#area") != -1) {
      string sAreaMessage = GetStringRight(sChatMessage, 5);
      SendMessageToPC(oSpeaker, "Sending: " + sAreaMessage);       //This is just for debug purposes to see the text is parsed correctly

       // Try to speak
      SpeakString("1: " + sAreaMessage, 1);
      SpeakString("100: " + sAreaMessage, 100);
      SpeakString("1000: " + sAreaMessage, 1000);
      SpeakString("Talk: " + sAreaMessage, TALKVOLUME_TALK);
      return FALSE;  //Return false since theoretically it should have spoken already
    }
  }
 
  return TRUE;
}

Modifié par last_dance, 28 octobre 2011 - 08:26 .


#2
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
This is in my csl library:

Basically i use this function to send the chat instead of using the tell.

CSLChatBroadcastMessageAtLocation( sTranslate, GetLocation(oThrower), oThrower, fBroadcastRange );

void CSLChatBroadcastMessageAtLocation( string sMessage, location lLocation, object oSpeaker = OBJECT_INVALID, float fRadiusSize = 20.0f )
{
		string sNewMessage;
		if ( GetIsObjectValid( oSpeaker ) && GetName(oSpeaker) != "")
		{
			sNewMessage = "<color=pink>"+GetName(oSpeaker)+":</color> "+sMessage;
		}
		else
		{
			sNewMessage = sMessage;
		}
		
		
		object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadiusSize, lLocation, TRUE, OBJECT_TYPE_CREATURE);
		while(GetIsObjectValid(oTarget))
		{
			if ( GetIsPC(oTarget) )
			{
				SendMessageToPC(oTarget, sNewMessage );
			}
			else
			{
				SendChatMessage(oSpeaker, oTarget, CHAT_MODE_TELL, sMessage, FALSE );
			}
			GetNextObjectInShape(SHAPE_SPHERE, fRadiusSize, lLocation, TRUE, OBJECT_TYPE_CREATURE);
		}
				
}
fRadiusSize would just be big enough to matter. You can technically comment out the npc sending as well, but i am intending on making those shouting to be a signal to the AI that they heard something despite the player being in move silent mode. You could also use getfirstpc/getnextpc and iterate all the players, if ( GetArea(oSpeaker) == GetArea( oPC ) ) would be used to compare if it's in the same area.

Something similar is below. This i am pretty sure is remotely descended from the DMFI function which is already doing the task for which you are trying to create code for. You'd have to pass in GetTag( GetArea( oSpeaker ) ) but it has drawbacks if the areas do not have unique tag names. ( which can happen if you use the new features which allow you to duplicate an area )
void CSLPlayerMessageBroadcast( string sMsg, int bDebuggersOnly = FALSE, int bIncludeDMs = FALSE, string sAreaTag = "" )
{
	object oPC = GetFirstPC();
	while ( oPC != OBJECT_INVALID )
	{
		if ( sAreaTag == "" ||  GetTag( GetArea( oPC ) ) == sAreaTag || ( bIncludeDMs == TRUE && CSLGetIsDM( oPC, TRUE ) ) )
		{
			if ( bDebuggersOnly == FALSE || GetLocalInt( oPC, "DEBUGGER" ) == TRUE )
			{
				SendMessageToPC( oPC, sMsg); 
			}
		}
		oPC = GetNextPC();
	}
}

This just an option i set up, per what they wanted on the Sea of Dragons PW.

I think the second parameter you have on SpeakString is wrong, i have it using channels like talk and shout, and silent shout instead of larger and larger numbers. No idea why you are looking for strings like #area which is a NWNx function to convert locations to strings in that code, that is never going to be inside the text unless the player types that in. Use getarea on the oSpeaker, then look for creatures in that area is what you want to do.

Modifié par painofdungeoneternal, 28 octobre 2011 - 08:40 .