Esempio n. 1
0
void cSpeech::talking(int s, QString speech) // PC speech
{
/*
	Unicode speech format
	byte = char, short = char[2], int = char[4], wchar = char[2] = unicode character

	Message Sent By Client:
	0xAD - Unicode Speech Request
	BYTE cmd(0xAD)
	short msgsize 1, 2
	byte type(0 = say, 2 = emote, 8 = whisper, 9 = yell) 3
	short color 4, 5
	short font 6, 7
	BYTE[4] lang(null terminated, "enu " for US english.) 8, 9, 10, 11
	wchar[?] text(null terminated, ?=(msgsize - 12)/2) 13
  
	Message Sent By Server:
	0xAE - Unicode Speech Message
	BYTE cmd(0xAE) 0
	short msgsize 1, 2
	BYTE[4] ser(ser of speaker, all 0xFF if none) 3, 4, 5, 6
	BYTE[2] model(id of speaker, all 0xFF if none)7, 8
	BYTE type 9
	short color 10, 11
	short font 12, 13
	BYTE[4] language(same as before) 14, 15, 16, 17
	BYTE[30] speaker's name(normal chars, not wchars) 18 - 48
	WCHAR[?] text(null terminated, ?=(msgsize - 48)/2

    Importnat note regarding 0xAD: since 2.0.7 clients send between lang and text 0...10 bytes. (we can ignore them safely)
	Those bytes get cut out in network.cpp correctly, so the buffer THIS functions sees is actualy what is written above.
    The actual data the client sends is differently though.
	Just noted this to prevent from debugging if somebody finds out client data doesn't fit to this description (LB) 

*/
	
	//char nonuni[512];
	unsigned char talk2[19];
	QByteArray unicodetext;
	char lang[4];
	char name[50] = {0,};	// it **IS** important to 0 out the remaining gaps
	
	P_CHAR pc_currchar = currchar[s];	
//	strcpy(nonuni, speech.latin1());

	// len+font+color+type = same postion for non unicode and unicode speech packets
	// but 8 ... x DIFFER a lot for unicode and non unicode packets !!!

	strncpy(name, pc_currchar->name.c_str(), 50);

	char speech_type       = buffer[s][3]; 
	UI16 speech_color	   = ShortFromCharPtr(&buffer[s][4]);
	char speech_fontbyte1  = buffer[s][6];
	char speech_fontbyte2  = buffer[s][7];

	int ucl = ( speech.length() * 2 ) + 2;
	int tl = ucl + 48 ;

	if (pc_currchar->unicode)
	{
		lang[0]=buffer[s][8];
		lang[1]=buffer[s][9];
		lang[2]=buffer[s][10];
		lang[3]=buffer[s][11];
		
		unicodetext.duplicate( (char*)&buffer[s][12], ucl );
	}
	else
	{
		lang[0]='E';
		lang[1]='N';
		lang[2]='U';
		lang[3]=0;
		
		char2wchar(speech.latin1());		// we are sending unicode response no matter if the speech request was non unicode or not
											// so convert to uni-text in case of non unicode
		unicodetext.duplicate( (char*)&temp, ucl );
	}

	/*
	clConsole.send("speech: %s\n",nonuni);
	clConsole.send("unicode speech:\n");
	for ( a=0; a < tl-48; a++) clConsole.send("%02i ",unicodetext[a]);
	clConsole.send("\n");*/




	//// Very important: do not use buffer[s][] anymore in this function !!!!
	//// unicode text that gets send is in unicodetext, nonunicode text for normal string processing in non uni code
//	string punt(nonuni);
	if (InputSpeech(speech, pc_currchar, s))	// handle things like renaming or describing an item
		return;

	if (pc_currchar->squelched)					// not allowed to talk
	{
		sysmessage(s, "You have been squelched.");
		return;
	}
			
	// AntiChrist
	pc_currchar->unhide();
		
	if (speech[0] == (char)SrvParams->commandPrefix() )
	{
		Commands->Command(s, speech.latin1());
		return;
	}

	if ( speech_type == '\x09' && pc_currchar->canBroadcast() )
	{
		broadcast(s);
		return;
	}
	
	talk2[0] = 0xAE;
	ShortToCharPtr(tl, &talk2[1]);
	LongToCharPtr(pc_currchar->serial, &talk2[3]);
	ShortToCharPtr(pc_currchar->id(), &talk2[7]);
	talk2[9] =  speech_type;
	ShortToCharPtr(speech_color, &talk2[10]);
	talk2[12] = speech_fontbyte1;
	talk2[13] = speech_fontbyte2;
	
	talk2[14] = lang[0];
	talk2[15] = lang[1];
	talk2[16] = lang[2];
	talk2[17] = lang[3];
	
	Xsend(s, talk2, 18);
	Xsend(s, name, 30);   
	Xsend(s, unicodetext.data(), unicodetext.size());   
	
	if (speech_type == 0 || speech_type == 2)
	{
		pc_currchar->saycolor = speech_color;
	}
	if (SrvParams->speechLog()) // Logging bugfixed by LB
	{
		char temp2[512];
		sprintf(temp2, "%s.speech_log", pc_currchar->name.c_str());
		sprintf((char*)temp, "%s [%x] [%i] said:\n%s\n", pc_currchar->name.c_str(), pc_currchar->serial, pc_currchar->account, speech.latin1());
		savelog((char*)temp, (char*)temp2);
	}
	
	//char SpeechUpr[512];
	//strcpy(SpeechUpr, nonuni);
	//strupr(SpeechUpr);
	QString SpeechUpr = speech.upper();
	//transform(SpeechUpr.begin(), SpeechUpr.end(), SpeechUpr.begin(), ::toupper);
	//if (!strcmp(SpeechUpr, "I RESIGN FROM MY GUILD"))
	if (SpeechUpr == "I RESIGN FROM MY GUILD")
	{
		GuildResign(s);
	}
	
	if (response(s,pc_currchar, SpeechUpr))
		return;  // Vendor responded already
	
	//if (strstr(SpeechUpr, "GUARDS"))
	if (SpeechUpr.contains("GUARDS"))
		callguards(currchar[s]);
	
	if (Boats->Speech(s, SpeechUpr))
		return;
	
	house_speech(s, SpeechUpr); // houses crackerjack 8/12/99			
	
	int i, j;
	for (i = 0; i < now; i++)
	{
		// AntiChrist - don't check line of sight for talking!!!
		if (inrange1(i, s) && perm[i] && i!=s)//&&line_of_sight(s, pc_currchar->pos.x, pc_currchar->pos.y, pc_currchar->pos.z, chars[currchar[i]].x, chars[currchar[i]].y, chars[currchar[i]].z, WALLS_CHIMNEYS + DOORS + FLOORS_FLAT_ROOFING))
		{
			Xsend(i, talk2, 18);
			Xsend(i, name, 30);
			if (pc_currchar->dead				// a ghost is talking
				&& !currchar[i]->dead		// Ghost can talk normally to other ghosts
				&& !currchar[i]->isGMorCounselor()// GM/Counselors can see ghosts talking always  Seers?
				&& currchar[i]->spiritspeaktimer == 0)
			{
				unsigned char ghostspeech[512];
				memcpy(&ghostspeech, unicodetext.data(), unicodetext.size());
				for (j = 1; j < ucl-2 ; j += 2)	// -2: dont override /0 /0 terminator !
				{
					if (ghostspeech[j] != 32)	// keep the blanks
						ghostspeech[j] = (ghostspeech[j]%2) ? 'O' : 'o';
				}
				Xsend(i, ghostspeech, ucl);		// send 'ghostified' speech "OOoooOo  Ooo"
			}
			else
				Xsend(i, unicodetext.data(), unicodetext.size());   
		}
	}
	
	if (pc_currchar->dead) return; // this makes it so npcs do not respond to dead people
	
	cChar* pc=NULL;
	cChar* pNpc=NULL;
	cRegion::RegionIterator4Chars ri(pc_currchar->pos);
	for (ri.Begin(); !ri.atEnd(); ri++)
	{	
		pc = ri.GetData();
		if (!pc->isSameAs(pc_currchar) 
			&& pc->isNpc()
			&& pc->dist(pc_currchar) <= 2)
		{
			pNpc=pc;
			break;
		}
	}
	if (pNpc && pNpc->speech)
	{
		Script *pScp=i_scripts[speech_script];
		if (!pScp->Open())
			return;
		char sect[512];
		sprintf(sect, "SPEECH %i", pNpc->speech);
		if (!pScp->find(sect)) 
		{
			pScp->Close();
			return;
		}
		int match = 0;
		strcpy(sect, "NO DEFAULT TEXT DEFINED");
		unsigned long loopexit = 0;
		do
		{
			pScp->NextLineSplitted();
			if (script1[0] != '}')
			{
				if (!(strcmp("DEFAULT", (char*)script1)))
				{
					strcpy(sect, (char*)script2);
				}
				if (!(strcmp("ON", (char*)script1)))
				{
					char scpUpr[500];
					strcpy(scpUpr,script2);
					strupr(scpUpr);
					if (SpeechUpr.find(scpUpr)!= string::npos)
						match=1;
				}
				if (!(strcmp("SAY", (char*)script1)))
				{
					if (match == 1)
					{
						npctalk(s, pNpc, (char*)script2, 0);
						match = 2;
					}
				}
				
				if (!(strcmp("TRG", (char*)script1))) // Added by Magius(CHE) §
				{							  
					if (match == 1)
					{
						pNpc->trigger = str2num(script2);
						scpMark m=pScp->Suspend();
						
						Trig->triggernpc(s, pNpc, 1);
						
						pScp->Resume(m);
						strcpy((char*)script1, "DUMMY");
						
						match = 2;
					}
				}
			}
		}
		while (script1[0] != '}'  && (++loopexit < MAXLOOPS));
		if (match == 0)
		{
			npctalk(s, pNpc, sect, 0);
		}
		pScp->Close();
	}
}
Esempio n. 2
0
void AttackStuff(NXWSOCKET  s, P_CHAR victim)
{
	if ( s < 0 || s >= now )
		return;

	P_CHAR attacker = MAKE_CHAR_REF( currchar[s] );
	VALIDATEPC( attacker );
	VALIDATEPC( victim );

	if( attacker->getSerial32() == victim->getSerial32() )
		return;

	
	if ( attacker->amxevents[EVENT_CHR_ONBEGINATTACK]) {
		g_bByPass = false;
		attacker->amxevents[EVENT_CHR_ONBEGINATTACK]->Call( attacker->getSerial32(), victim->getSerial32() );
		if (g_bByPass==true) return;
	}

	if ( victim->amxevents[EVENT_CHR_ONBEGINDEFENSE]) {
		g_bByPass = false;
		victim->amxevents[EVENT_CHR_ONBEGINDEFENSE]->Call( victim->getSerial32(), attacker->getSerial32() );
		if (g_bByPass==true) return;
	}
	/*
	attacker->runAmxEvent( EVENT_CHR_ONBEGINATTACK, attacker->getSerial32(), victim->getSerial32() );
	if (g_bByPass==true)
		return;
	victim->runAmxEvent( EVENT_CHR_ONBEGINDEFENSE, victim->getSerial32(), attacker->getSerial32() );
	if (g_bByPass==true)
		return;
	*/
	attacker->targserial=victim->getSerial32();
	attacker->unHide();
	attacker->disturbMed();

	if( victim->dead || victim->hp <= 0 )//AntiChrist
	{
		attacker->sysmsg( TRANSLATE("That person is already dead!") );
		return;
	}

	if ( victim->npcaitype==NPCAI_PLAYERVENDOR)
	{
		attacker->sysmsg( TRANSLATE("%s cannot be harmed."), victim->getCurrentNameC() );
		return;
	}

	SndAttackOK(s, victim->getSerial32());	//keep the target highlighted
	if (!( victim->targserial== INVALID))
	{
		victim->attackerserial=attacker->getSerial32();
		victim->ResetAttackFirst();
	}
	attacker->SetAttackFirst();
	attacker->attackerserial=victim->getSerial32();

	if( victim->guarded )
	{
		NxwCharWrapper sc;
		sc.fillOwnedNpcs( victim, false, false );
		for ( sc.rewind(); !sc.isEmpty(); sc++ )
		{
			P_CHAR guard = sc.getChar();
			if ( ISVALIDPC( guard ) )
				if ( guard->npcaitype == NPCAI_PETGUARD && ( attacker->distFrom( guard )<= 10 ) )
					npcattacktarget(attacker, guard);
		}
	}

	if ((region[ victim->region].priv & RGNPRIV_GUARDED) && (SrvParms->guardsactive))
	{
		if (victim->IsGrey())
			attacker->SetGrey();

		if (victim->npc==0 && victim->IsInnocent() && (!victim->IsGrey()) && Guildz.compareGuilds( attacker->getGuild(), victim->getGuild() )==0) //REPSYS
		{
			criminal( attacker );
			if (ServerScp::g_nInstantGuard==1)
				npcs::SpawnGuard(attacker, victim,attacker->getPosition() );
		}
		else if( victim->npc && victim->IsInnocent() && !victim->HasHumanBody() && victim->npcaitype!=NPCAI_TELEPORTGUARD )
		{
			criminal( attacker );
			if (ServerScp::g_nInstantGuard==1)
				npcs::SpawnGuard(attacker, victim, attacker->getPosition() );
		}
		else if( victim->npc && victim->IsInnocent() && victim->HasHumanBody() && victim->npcaitype!=NPCAI_TELEPORTGUARD )
		{
			victim->talkAll( TRANSLATE("Help! Guards! I've been attacked!"), 1);
			criminal( victim );
			callguards(DEREF_P_CHAR(victim)); // Sparhawk must check if npcs can call guards
		}
		else if( victim->npc && victim->npcaitype==NPCAI_TELEPORTGUARD)
		{
			criminal( attacker );
			npcattacktarget(victim, attacker);
		}
		else if ((victim->npc || victim->tamed) && !victim->war && victim->npcaitype!=NPCAI_TELEPORTGUARD)
		{
			victim->fight( attacker );
		}
		else
		{
			victim->setNpcMoveTime();
		}
		//attacker->emoteall( "You see %s attacking %s!", 1, attacker->getCurrentNameC(), victim->getCurrentNameC() );
	}
	else	// not a guarded area
	{
		if ( victim->IsInnocent())
		{
			if ( victim->IsGrey())
				attacker->SetGrey();
			if (!victim->npc && (!victim->IsGrey()) && Guildz.compareGuilds(attacker->getGuild(), victim->getGuild() )==0)
			{
				criminal( attacker );
			}
			else if (victim->npc && victim->tamed)
			{
				criminal( attacker );
				npcattacktarget(victim, attacker);
			}
			else if (victim->npc)
			{
				criminal( attacker );
				npcattacktarget(victim, attacker);
				if (victim->HasHumanBody() )
				{
					victim->talkAll(TRANSLATE("Help! Guards! Tis a murder being commited!"), 1);
				}
			}
		}
	}

}
Esempio n. 3
0
void RcvAttack(P_CLIENT ps)
{
	UOXSOCKET s = ps->GetSocket();
	P_CHAR pc_currchar = ps->getPlayer();
	int j;

	SERIAL serial=calcserial(buffer[s][1],buffer[s][2],buffer[s][3],buffer[s][4]);
	if(serial == INVALID_SERIAL) return;
	P_CHAR pc_i = FindCharBySerPtr(&buffer[s][1]);
	if(pc_i == NULL) return;	//to avoid problems
	
	if(pc_currchar->dead)//AntiChrist stuff
	{
		if(SrvParams->persecute())
		{//start persecute stuff - AntiChrist
			pc_currchar->targ = pc_i->serial;
			if(pc_currchar->targ==INVALID_SERIAL) return;
			else Skills->Persecute(s);
			return;
		} else
		{
			sysmessage(s,"You are dead and cannot do that.");
			return;
		}
	}
	if(pc_currchar->cell>0)
	{
		sysmessage(s,"There is no fighting in the jail cells!");
		return;
	}

	if(!pc_currchar->dead)
	{
		pc_currchar->targ = serial;
		pc_currchar->unhide();
		pc_currchar->disturbMed(s);

		
		if(pc_i->dead || pc_i->hp<=0)//AntiChrist
		{
			sysmessage(s,"That person is already dead!");
			return;
		}
		
		if (pc_i->npcaitype==17)//PlayerVendors
		{
			sprintf((char*)temp, "%s cannot be harmed.",pc_i->name.c_str());
			sysmessage(s, (char*)temp);
			return;
		}
		
		SndAttackOK(s, pc_i->serial);	//keep the target highlighted       
		if (!(pc_i->targ == INVALID_SERIAL))
		{
			pc_i->attacker = pc_currchar->serial;
			pc_i->resetAttackFirst();
		}
		pc_currchar->setAttackFirst();
		pc_currchar->attacker = pc_i->serial;
 
		pc_currchar->dir = chardir(pc_currchar, pc_i);	// turn to attacker, LB (& Duke)

		updatechar(pc_currchar);

		if( pc_i->guarded )
		{
			AllCharsIterator iter_char;
			for (iter_char.Begin(); !iter_char.atEnd(); iter_char++)
			{
				P_CHAR toCheck = iter_char.GetData();
				if (pc_i->Owns(toCheck) && toCheck->npcaitype == 32 && chardist( pc_currchar, toCheck )<= 10 )
				{
					npcattacktarget( pc_currchar, toCheck );
				}
			}
		}

		if (pc_i->inGuardedArea() && SrvParams->guardsActive())
		{
			if (pc_i->isPlayer() && pc_i->isInnocent() && GuildCompare( pc_currchar, pc_i )==0) //REPSYS
			{
				criminal( pc_currchar );
				Combat->SpawnGuard(pc_currchar, pc_i ,pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
			}
			else if( pc_i->isNpc() && pc_i->isInnocent() && !pc_i->isHuman() && pc_i->npcaitype!=4 )
			{
				criminal( pc_currchar );
				Combat->SpawnGuard(pc_currchar, pc_i, pc_currchar->pos.x,pc_currchar->pos.y,pc_currchar->pos.z);
			}
			else if( pc_i->isNpc() && pc_i->isInnocent() && pc_i->isHuman() && pc_i->npcaitype!=4 )
			{
				npctalkall(pc_i, "Help! Guards! I've been attacked!", 1);
				criminal( pc_currchar );
				callguards(pc_i);
			}
			else if( pc_i->isNpc() && pc_i->npcaitype==4)
			{
				criminal( pc_currchar );
				npcattacktarget(pc_i, pc_currchar);
			}
			else if ((pc_i->isNpc() || pc_i->tamed) && !pc_i->war && pc_i->npcaitype!=4) // changed from 0x40 to 4, cauz 0x40 was removed LB
			{
				npcToggleCombat(pc_i);
				pc_i->setNextMoveTime();
			}
			else
			{
				pc_i->setNextMoveTime();
			}
			
			sprintf((char*)temp, "You see %s attacking %s!", pc_currchar->name.c_str(), pc_i->name.c_str());
			
			for (j=0;j<now;j++)
			{
				if((inrange1(s, j) && perm[j]) && (s!=j))
				{
					pc_i->emotecolor = 0x0026;
					npcemote(j, pc_currchar, (char*)temp,1);
				}
			}
		}
		else	// not a guarded area
		{
			if (pc_i->isInnocent())
			{
				if (pc_i->isPlayer() && GuildCompare( pc_currchar, pc_i )==0)
				{
					criminal( pc_currchar );
				}
				else if (pc_i->isNpc() && pc_i->tamed)
				{
					criminal( pc_currchar );
					npcattacktarget(pc_i, pc_currchar);
				}
				else if (pc_i->isNpc())
				{
					criminal( pc_currchar );
					npcattacktarget(pc_i, pc_currchar);
					if (pc_i->isHuman() )
					{
						npctalkall(pc_i, "Help! Guards! Tis a murder being commited!", 1);
					}
				}
			}
		}
	}
}