Beispiel #1
0
void cCharStuff::cDragonAI::HealMagic(P_CHAR pc_i, unsigned int currenttime)
{
	if (currenttime >= pc_i->spatimer)
	{
		if (pc_i->poisoned)
		{
			Magic->NPCCure(pc_i);
		}
		else if (pc_i->hp < (pc_i->st/2))
		{
			Magic->NPCHeal(pc_i);
		}
		if (pc_i->targ != INVALID_SERIAL)
			npcattacktarget(pc_i, FindCharBySerial(pc_i->targ));
	}
	DoneAI(pc_i, currenttime);
}
Beispiel #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);
				}
			}
		}
	}

}
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);
					}
				}
			}
		}
	}
}
Beispiel #4
0
void cCharStuff::CheckAI(unsigned int currenttime, int i) //Lag Fix -- Zippy
{
	int d, onl;
	unsigned int chance;
	//unsigned int StartGrid, getcell, increment, a, checkgrid;
	P_CHAR pc_i = MAKE_CHARREF_LR(i);
	if (i<0 || i>cmem) return;

	if (!(nextnpcaitime<=currenttime||(overflow))) return;
    // in npc.scp add script # for npc`s ai
	// case - script - case - script -   case - script -  case - script
	//   0   -  0     -  4    -  4     -  8    -  8     -  12   -  C
	//   1   -  1     -  5    -  5     -  9    -  9     -  13   -  D
	//   2   -  2     -  6    -  6     -  10   -  A     -  14   -  E
	//   3   -  3     -  7    -  7     -  11   -  B     -  15   -  F
	// case - script - case - script
	//   16  -  10    -  20   -  14
	//   17  -  11    -  21   -  15
	//   18  -  12    -  22   -  16
	//   19  -  13    -  23   -  17  ...this is just a guide...Ripper
	switch(pc_i->npcaitype)
	{
	case 0: // Shopkeepers greet players..Ripper
		if(server_data.VendorGreet==1 && pc_i->isNpc() && pc_i->shop==1 && pc_i->id1==0x01 && (pc_i->id2==0x90 || pc_i->id2==0x91))
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 3)
						continue;
					if (pc->isInvul() || pc->isNpc() || pc->dead || !pc->isInnocent() || !onl)
					    continue;
						sprintf((char*)temp,"Hello %s, Welcome to my shop, How may i help thee?.", pc->name);
						npctalkall(i,(char*)temp,1);
						pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
				}
			}
		}
		break;
	case 1: // good healers
		if(!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (!pc->dead || d > 3 || pc->isNpc() || !onl)
						continue;
					if (pc->isMurderer()) 
					{
						npctalkall(i, "I will nay give life to a scoundrel like thee!",1);
						return;
					}
					else if (pc->isCriminal()) 
					{
						npctalkall(i, "I will nay give life to thee for thou art a criminal!",1);
						return;
					}
					else if (pc->isInnocent())
					{
						npcaction(i, 0x10);
						Targ->NpcResurrectTarget(DEREF_P_CHAR(pc));
						staticeffect(DEREF_P_CHAR(pc), 0x37, 0x6A, 0x09, 0x06);
						switch(RandomNum(0, 4)) 
						{
						case 0: npctalkall(i, "Thou art dead, but 'tis within my power to resurrect thee.  Live!",1);			break;
						case 1: npctalkall(i, "Allow me to resurrect thee ghost.  Thy time of true death has not yet come.",1);	break;
						case 2: npctalkall(i, "Perhaps thou shouldst be more careful.  Here, I shall resurrect thee.",1);		break;
						case 3: npctalkall(i, "Live again, ghost!  Thy time in this world is not yet done.",1);					break;
						case 4: npctalkall(i, "I shall attempt to resurrect thee.",1);											break;
						}
					}
				}
			}
		}
		break;
	case 2 : // Monsters, PK's - (stupid NPCs)
		if (!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					chance = RandomNum(1, 100);
					if (DEREF_P_CHAR(pc) == i)
						continue;
					if (d>SrvParms->attack_distance)
						continue;
					if (onl &&(pc->isInvul() || pc->isHidden() || pc->dead))
						continue;
					if (pc->isNpc() &&(pc->npcaitype == 2) || pc->npcaitype == 1)
						continue;
					if (server_data.monsters_vs_animals == 0 && (strlen(pc->title) > 0 || !onl))
						continue;
					if (server_data.monsters_vs_animals == 1 && chance > server_data.animals_attack_chance)
						continue;
					if (pc_i->baseskill[MAGERY]>400)
					{
						if (pc_i->hp < (pc_i->st/2))
						{
							npctalkall(i, "In Vas Mani", 0);
							Magic->NPCHeal(i);
						}
						if (pc_i->poisoned)
						{
							npctalkall(i, "An Nox", 0);
							Magic->NPCCure(i);
						}
						if (pc->priv2&0x20)
						{
							npctalkall(i, "An Ort", 0);
							Magic->NPCDispel(i, DEREF_P_CHAR(pc));
						}
					}
					npcattacktarget(i, DEREF_P_CHAR(pc));
					return;
				}
			}
		}
		break;
	case 3 : //Evil Healers
		if(!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (!pc->dead || d > 3 || pc->isNpc() || !onl)
						continue;
					if (pc->isInnocent())
					{
						npctalkall(i, "I dispise all things good. I shall not give thee another chance!",1);
						return;
					}
					else
					{
						npcaction(i, 0x10);
						Targ->NpcResurrectTarget(DEREF_P_CHAR(pc));
						staticeffect(DEREF_P_CHAR(pc), 0x37, 0x09, 0x09, 0x19); //Flamestrike effect
						switch(RandomNum(0, 4)) 
						{
						   case 0: npctalkall(i, "Fellow minion of Mondain, Live!!",1); break;
						   case 1: npctalkall(i, "Thou has evil flowing through your vains, so I will bring you back to life.",1); break;
						   case 2: npctalkall(i, "If I res thee, promise to raise more hell!.",1); break;
						   case 3: npctalkall(i, "From hell to Britannia, come alive!.",1); break;
						   case 4: npctalkall(i, "Since you are Evil, I will bring you back to consciouness.",1); break;
						}
					}
				}
			}
		}
		break;
	case 4 : // Guards
		if (!pc_i->war	// guard isnt busy 
			&& pc_i->inGuardedArea())	// this region is guarded
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 10 || pc->isInvul() || pc->dead || !onl)
						continue;
						npcattacktarget(i, DEREF_P_CHAR(pc));
						npctalkall(i, "Thou shalt regret thine actions, swine!",1); // ANTISPAM !!! LB
				}
			}
		}
		break;
	case 5: // npc beggars
		if (!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 3 || pc->isInvul() || pc->isNpc() || pc->dead || !onl || !pc->isInnocent())
					    continue;
						int beg= RandomNum (0,2);
						{
							switch (beg)
							{
								case 0: npctalkall(i,"Could thou spare a few coins?",1);
										pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
										break;
								case 1: npctalkall(i,"Hey buddy can you spare some gold?",1);
										pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
										break;
								case 2: npctalkall(i,"I have a family to feed, think of the children.",1);
										pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
										break;
								default:
										break;
							}
						}
				}
			}
		}
		break;
	case 6: break; // Ripper- chaos guards.
	case 7: break; // Ripper- order guards.
	case 8: break; //morrolan - old banker
	case 9 : // in world guards, they dont teleport out...Ripper
		if (!pc_i->war	// guard isnt busy 
			&& pc_i->inGuardedArea())	// this region is guarded
		{	// this bracket just to keep compiler happy
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (i==DEREF_P_CHAR(pc) || d > 3 || pc->isInvul() || pc->dead || !onl)
						continue;
					if ( pc->isPlayer() && pc->crimflag > 0 )
					{
						sprintf((char*)temp,"You better watch your step %s, I am watching thee!!", pc->name);
						npctalkall(i,(char*)temp,1);
						pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
					}
					else if ( pc->isPlayer() && pc->isInnocent() && !pc->dead )
					{
						sprintf((char*)temp,"%s is an upstanding citizen, I will protect thee in %s.", pc->name, region[pc->region].name);
						npctalkall(i,(char*)temp,1);
						pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
					}
					else if ( d<=10 && (
							(pc->isNpc() && (pc->npcaitype==2))	// evil npc
							|| (pc->isPlayer() && !(pc->isInnocent()) && !(pc->isCriminal()))	// a player, not grey or blue
							|| (pc->attackfirst==1)))	// any agressor
					{
						pc_i->pos.x=pc->pos.x; //Ripper..guards teleport to enemies.
						pc_i->pos.y=pc->pos.y;
						pc_i->pos.z=pc->pos.z;
						soundeffect2(i, 0x01, 0xFE); // crashfix, LB
						staticeffect(i, 0x37, 0x2A, 0x09, 0x06);
						npcattacktarget(i, DEREF_P_CHAR(pc));
						npctalkall(i, "Thou shalt regret thine actions, swine!",1); // ANTISPAM !!! LB
						return;
					}
				}
			}
		}
		break;
	case 10: // Tamed Dragons ..not white wyrm..Ripper
		// so regular dragons attack reds on sight while tamed.
		if(pc_i->isNpc() && pc_i->tamed)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if(d > 10 || pc->isPlayer() || pc->npcaitype!=2)
						continue;
						npcattacktarget(i,DEREF_P_CHAR(pc));
						return;
				}
			}
		}
		break;
	case 11 : // add NPCAI B in scripts to make them attack reds. (Ripper)
		if (!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 10 || pc->isInvul() || pc->dead || !onl)
						continue;
					if (pc->npcaitype!=2 || !pc->isCriminal() || !pc->isMurderer())
					    continue;
						npcattacktarget(i, DEREF_P_CHAR(pc));
				}
			}
		}
		break;
	case 17: break; //Zippy Player Vendors.
	case 30: // why is this the same as case 50???..Ripper
		if (!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 10 || pc->isInvul() || pc->dead || pc->npcaitype!=2 || !onl)
						continue;
						npcattacktarget(i, DEREF_P_CHAR(pc));
						return;
				}
			}
		}
		break;
	case 32: // Pets Guarding..Ripper
		if(pc_i->isNpc() && pc_i->tamed)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 10 || pc->isNpc() || pc->dead || !pc->guarded || !onl)
						continue;
						if(pc->Owns(pc_i))
						{
							npcattacktarget(i,pc->attacker);
							return;
						}
				}
			}
		}
		break;
	case 50://EV/BS
		if (!pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (d > 10 || pc->isInvul() || pc->dead || !onl)
						continue;
						npcattacktarget(i, DEREF_P_CHAR(pc));
						return;
				}
			}
		}
		break;
		// Case 60-70 is Skyfires new AI
	case 96:
	case 60: //Skyfire - Dragon AI
		if (pc_i->war)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); ri.GetData() != ri.End(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
					onl = online(DEREF_P_CHAR(pc));
					d = chardist(i, DEREF_P_CHAR(pc));
					if (pc->isNpc() || pc->dead || !onl)
						continue;
						if (d > 4 && pc_i->attacker==DEREF_P_CHAR(pc))
						{
							if (Combat->GetBowType(DEREF_P_CHAR(pc))!=0)
							{
								pc_i->pos.x=pc->pos.x;
								pc_i->pos.y=pc->pos.y;
								pc_i->pos.z=pc->pos.z;
								pc_i->dir=pc->dir;
								teleport(i);
								npctalkall(i,"Foolish Mortal!",0);
							}
						}
						else
						{
							switch(RandomNum(0, 4))
							{
							case 0:	Magic->NPCEBoltTarget(i,DEREF_P_CHAR(pc));			break;
							case 1:	Magic->NPCFlameStrikeTarget(i,DEREF_P_CHAR(pc));	break;
							case 2:	Magic->ParalyzeSpell(i,DEREF_P_CHAR(pc));			break;
							case 3:	Magic->NPCLightningTarget(i,DEREF_P_CHAR(pc));		break;
							case 4:	Magic->ParalyzeSpell(i,DEREF_P_CHAR(pc));			break;
							}
						}
					}
					if (pc_i->hp<(pc_i->st/2))
						Magic->NPCHeal(i);
					if (pc_i->poisoned)
						Magic->NPCCure(i);
					if (pc->priv2&0x20)
						Magic->NPCDispel(i,DEREF_P_CHAR(pc));
					npcattacktarget(i, DEREF_P_CHAR(pc));
					return;
			}
		}
		else
		{
			if (pc_i->hp<(pc_i->st/2))
				Magic->NPCHeal(i);
			if (pc_i->poisoned)
				Magic->NPCCure(i);
		}
		break;
	default:
		clConsole.send("ERROR: cCharStuff::CheckAI-> Error npc %i (%x %x %x %x) has invalid AI type %i\n",i,pc_i->ser1,pc_i->ser2,pc_i->ser3,pc_i->ser4,pc_i->npcaitype); //Morrolan
		return;
	}// switch
}// void checknpcai
Beispiel #5
0
void cCharStuff::CheckAI(unsigned int currenttime, P_CHAR pc_i) // Lag Fix -- Zippy
{
	int d;
	unsigned int chance;
	if ( pc_i == NULL )
		return;
	
	if (!(nextnpcaitime <= currenttime || (overflow)))
		return;
    // in npc.scp add script # for npc`s ai
	// case - script - case - script -   case - script -  case - script
	//   0   -  0     -  4    -  4     -  8    -  8     -  12   -  C
	//   1   -  1     -  5    -  5     -  9    -  9     -  13   -  D
	//   2   -  2     -  6    -  6     -  10   -  A     -  14   -  E
	//   3   -  3     -  7    -  7     -  11   -  B     -  15   -  F
	// case - script - case - script
	//   16  -  10    -  20   -  14
	//   17  -  11    -  21   -  15
	//   18  -  12    -  22   -  16
	//   19  -  13    -  23   -  17  ...this is just a guide...Ripper
	switch (pc_i->npcaitype)
	{
		case 0: // Shopkeepers greet players..Ripper
			if (SrvParams->shopInvul() == 1 && pc_i->isNpc() && pc_i->shop && pc_i->isHuman())
			{
				pc_i->makeInvulnerable();
			}else{
				pc_i->makeVulnerable();
			}
			if (SrvParams->vendorGreet() == 1 && pc_i->isNpc() && pc_i->shop && pc_i->isHuman())
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc );
						if (d > 3)
							continue;
						if (pc->isNpc() || !online(pc))
							continue;
						if (pc->isInvul() || pc->dead || !pc->isInnocent())
							continue;
						sprintf((char*)temp, "Hello %s, Welcome to my shop, How may i help thee?.", pc->name.c_str());
						npctalkall(pc_i, (char*)temp, 1);
						pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
					}
				}
			}
			break;
		case 1: // good healers
			if (!pc_i->war)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc );
						if (d > 3)
							continue;
						if (pc->isNpc() || !online(pc))
							continue;
						if (!pc->dead)
							continue;
						if (pc->isMurderer()) 
						{
							npctalkall(pc_i, "I will nay give life to a scoundrel like thee!", 1);
							return;
						}
						else if (pc->isCriminal()) 
						{
							npctalkall(pc_i, "I will nay give life to thee for thou art a criminal!", 1);
							return;
						}
						else if (pc->isInnocent())
						{
							npcaction(pc_i, 0x10);
							Targ->NpcResurrectTarget(pc);
							staticeffect(pc, 0x37, 0x6A, 0x09, 0x06);
							switch (RandomNum(0, 4)) 
							{
							case 0: 
								npctalkall(pc_i, "Thou art dead, but 'tis within my power to resurrect thee.  Live!", 1);
								break;
							case 1: 
								npctalkall(pc_i, "Allow me to resurrect thee ghost.  Thy time of true death has not yet come.", 1);
								break;
							case 2: 
								npctalkall(pc_i, "Perhaps thou shouldst be more careful.  Here, I shall resurrect thee.", 1);
								break;
							case 3: 
								npctalkall(pc_i, "Live again, ghost!  Thy time in this world is not yet done.", 1);
								break;
							case 4: 
								npctalkall(pc_i, "I shall attempt to resurrect thee.", 1);
								break;
							}
						}
					}
				}
			}
			break;
		case 2 : // Monsters, PK's - (stupid NPCs)
			if (!pc_i->war)
			{
				// Get the one with the least distance!
				P_CHAR Victim = NULL;
				UI32 minDist;

				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					
					if( pc == NULL )
						continue;

					d = chardist( pc_i, pc );
					chance = RandomNum(1, 100);
					
					if( ( !pc->isNpc() ) && ( !online( pc ) ) )
						continue;

					if ( d > SrvParams->attack_distance() )
						continue;

					if ( pc->isInvul() || pc->isHidden() || pc->dead )
						continue;

					if ( pc->isNpc() && ( pc->npcaitype == 2 || pc->npcaitype == 1 ) )
						continue;

					if ( SrvParams->monsters_vs_animals() == 0 && ( pc->title.size() <= 0 && !pc->isHuman() ) )
						continue;

					if ( SrvParams->monsters_vs_animals() == 1 && chance > SrvParams->animals_attack_chance() )
						continue;

					// If the distance is below the minimal distance we found
					if( ( Victim == NULL ) || ( minDist > d ) )
					{
						Victim = pc;
						minDist = d;
					}

				}

				if (pc_i->baseskill[MAGERY]>400)
				{
					if (pc_i->hp <(pc_i->st/2))
					{
						npctalkall(pc_i, "In Vas Mani", 0);
						Magic->NPCHeal(pc_i);
					}
					else if (pc_i->poisoned)
					{
						npctalkall(pc_i, "An Nox", 0);
						Magic->NPCCure(pc_i);
					}
					else if ( Victim && Victim->priv2&0x20 )
					{
						npctalkall(pc_i, "An Ort", 0);
						Magic->NPCDispel(pc_i, Victim);
					}
				}

				// We found a victim
				if( Victim != NULL )
					npcattacktarget(pc_i, Victim);

				return;
			}
			break;
		case 3 : // Evil Healers
			if (!pc_i->war)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc );
						if (d > 3)
							continue;
						if (pc->isNpc() || !online(pc))
							continue;
						if (!pc->dead)
							continue;
						if (pc->isInnocent())
						{
							npctalkall(pc_i, "I dispise all things good. I shall not give thee another chance!", 1);
							return;
						}
						else
						{
							npcaction(pc_i, 0x10);
							Targ->NpcResurrectTarget(pc);
							staticeffect(pc, 0x37, 0x09, 0x09, 0x19); // Flamestrike effect
							switch (RandomNum(0, 4)) 
							{
							case 0: npctalkall(pc_i, "Fellow minion of Mondain, Live!!", 1);											break;
							case 1: npctalkall(pc_i, "Thou has evil flowing through your vains, so I will bring you back to life.", 1);	break;
							case 2: npctalkall(pc_i, "If I res thee, promise to raise more hell!.", 1);									break;
							case 3: npctalkall(pc_i, "From hell to Britannia, come alive!.", 1);										break;
							case 4: npctalkall(pc_i, "Since you are Evil, I will bring you back to consciouness.", 1);					break;
							}
						}
					}
				}
			}
			break;
		case 4 : // Teleporting Guards
			if (!pc_i->war	// guard isnt busy 
				&& pc_i->inGuardedArea())	// this region is guarded
			{	// this bracket just to keep compiler happy

				if (SrvParams->guardsInvul() == 1)
				{
				    pc_i->makeInvulnerable();
				}else{
				    pc_i->makeVulnerable();
				}

				P_CHAR Victim = NULL;
				UI32 minDist;

				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc);

						if( ( !pc->isNpc() ) && ( !online( pc ) ) )
						    continue;
						if (pc_i == pc || d > SrvParams->attack_distance() || pc->isInvul() || pc->dead)
							continue;
						if (!pc->inGuardedArea())
							continue;
						// If the distance is below the minimal distance we found
					    if( ( Victim == NULL ) || ( minDist > d ) )
						{
						   Victim = pc;
						   minDist = d;
						}
						if (pc->isPlayer() && pc->crimflag > 0 && d <= 3)
						{
							sprintf((char*)temp, "You better watch your step %s, I am watching thee!!", pc->name.c_str());
							npctalkall(pc_i, (char*)temp, 1);
							pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
						}
						else if (pc->isPlayer() && pc->isInnocent() && d <= 3)
						{
							sprintf((char*)temp, "%s is an upstanding citizen, I will protect thee in %s.", pc->name.c_str(), region[pc->region].name);
							npctalkall(pc_i, (char*)temp, 1);
							pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
						}
						else if (d <= SrvParams->attack_distance() &&(
							(pc->isNpc() &&(pc->npcaitype == 2))	// evil npc
							||(pc->isPlayer() && pc->isMurderer() && !(pc->isInnocent()) || pc->isCriminal()))	// a player,is murderer & not grey or blue
							||(pc->attackfirst == 1))	// any agressor
						{
							pc_i->pos.x = pc->pos.x; // Ripper..guards teleport to enemies.
							pc_i->pos.y = pc->pos.y;
							pc_i->pos.z = pc->pos.z;
							soundeffect2(pc_i, 0x01FE); // crashfix, LB
							staticeffect(pc_i, 0x37, 0x2A, 0x09, 0x06);
							// We found a victim
				            if( Victim != NULL )
							npcattacktarget(pc_i, Victim);
							npctalkall(pc_i, "Thou shalt regret thine actions, swine!", 1); // ANTISPAM !!! LB
							return;
						}
					}
				}
			}
			break;
		case 5: // npc beggars
			if (!pc_i->war)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc );
						if (d > 3)
							continue;
						if (pc->isNpc() || !online(pc))
							continue;
						if (pc->isInvul() || pc->dead || !pc->isInnocent())
							continue;
						int beg= RandomNum(0, 2);
						{
							switch (beg)
							{
							case 0: 
								npctalkall(pc_i, "Could thou spare a few coins?", 1);
								pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
								break;
							case 1: 
								npctalkall(pc_i, "Hey buddy can you spare some gold?", 1);
								pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
								break;
							case 2: 
								npctalkall(pc_i, "I have a family to feed, think of the children.", 1);
								pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
								break;
							default:
								break;
							}
						}
					}
				}
			}
			break;
		case 6: 
			break; // Ripper- chaos guards.
		case 7: 
			break; // Ripper- order guards.
		case 8: 
			break; // morrolan - old banker
		case 9 : // in world guards, they dont teleport out...Ripper
			if (!pc_i->war	// guard isnt busy 
				&& pc_i->inGuardedArea())	// this region is guarded
			{	// this bracket just to keep compiler happy

				if (SrvParams->guardsInvul() == 1)
				{
				    pc_i->makeInvulnerable();
				}else{
				    pc_i->makeVulnerable();
				}

				P_CHAR Victim = NULL;
				UI32 minDist;

				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc);

						if( ( !pc->isNpc() ) && ( !online( pc ) ) )
						    continue;
						if (pc_i == pc || d > SrvParams->attack_distance() || pc->isInvul() || pc->dead)
							continue;
						if (!pc->inGuardedArea())
							continue;
						// If the distance is below the minimal distance we found
					    if( ( Victim == NULL ) || ( minDist > d ) )
						{
						   Victim = pc;
						   minDist = d;
						}
						if (pc->isPlayer() && pc->crimflag > 0 && d <= 3)
						{
							sprintf((char*)temp, "You better watch your step %s, I am watching thee!!", pc->name.c_str());
							npctalkall(pc_i, (char*)temp, 1);
							pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
						}
						else if (pc->isPlayer() && pc->isInnocent() && d <= 3)
						{
							sprintf((char*)temp, "%s is an upstanding citizen, I will protect thee in %s.", pc->name.c_str(), region[pc->region].name);
							npctalkall(pc_i, (char*)temp, 1);
							pc_i->antispamtimer = uiCurrentTime + MY_CLOCKS_PER_SEC*30;
						}
						else if (d <= SrvParams->attack_distance() &&(
							(pc->isNpc() &&(pc->npcaitype == 2))	// evil npc
							||(pc->isPlayer() && pc->isMurderer() && !(pc->isInnocent()) || pc->isCriminal()))	// a player,is murderer & not grey or blue
							||(pc->attackfirst == 1))	// any agressor
						{
							pc_i->pos.x = pc->pos.x; // Ripper..guards teleport to enemies.
							pc_i->pos.y = pc->pos.y;
							pc_i->pos.z = pc->pos.z;
							soundeffect2(pc_i, 0x01FE); // crashfix, LB
							staticeffect(pc_i, 0x37, 0x2A, 0x09, 0x06);
							// We found a victim
				            if( Victim != NULL )
							npcattacktarget(pc_i, Victim);
							npctalkall(pc_i, "Thou shalt regret thine actions, swine!", 1); // ANTISPAM !!! LB
							return;
						}
					}
				}
			}
			break;
		case 10: // Tamed Dragons ..not white wyrm..Ripper
			// so regular dragons attack reds on sight while tamed.
			if (pc_i->isNpc() && pc_i->tamed)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc );
						if (d > SrvParams->attack_distance())
							continue;
						if (pc->isPlayer())
							continue;
						if (pc->isNpc() && pc->npcaitype != 2)
							continue;
						npcattacktarget(pc_i, pc);
						return;
					}
				}
			}
			break;
		case 11 : // add NPCAI B in scripts to make them attack reds. (Ripper)
			if (!pc_i->war)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist( pc_i, pc );
						if (d > SrvParams->attack_distance())
							continue;
						if( ( !pc->isNpc() ) && ( !online( pc ) ) )
						    continue;
						if (pc->isInvul() || pc->dead)
							continue;
						if (!(pc->npcaitype == 2 || pc->isMurderer()))
							continue;
						npcattacktarget(pc_i, pc);
					}
				}
			}
			break;
		case 17: 
			break; // Zippy Player Vendors.
		case 18: // Ripper.. Escort speech.
		if (!pc_i->war && pc_i->questType == ESCORTQUEST)
		{
			cRegion::RegionIterator4Chars ri(pc_i->pos);
			for (ri.Begin(); !ri.atEnd(); ri++)
			{
				P_CHAR pc = ri.GetData();
				if (pc != NULL)
				{
				    d = chardist(pc_i, pc);
					if (d > 10)
					    continue;
					if( ( pc->isNpc() ) && ( !online( pc ) ) )
						    continue;
				    if (pc->dead)
					    continue;

				    sprintf((char*)temp,"I am waiting for my escort to %s, Will you take me?", region[pc_i->questDestRegion].name);
				    npctalkall(pc_i,(char*)temp,1);
				    pc_i->antispamtimer=uiCurrentTime+MY_CLOCKS_PER_SEC*30;
				    return;
				}
			}
		}
		break;
		case 19:
			break; // real estate broker...Ripper
		case 32: // Pets Guarding..Ripper
			if (pc_i->isNpc() && pc_i->tamed)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist(pc_i, pc);
						if (d > SrvParams->attack_distance())
							continue;
						if( ( !pc->isNpc() ) && ( !online( pc ) ) )
						    continue;
						if (pc->dead)
							continue;
						if (!pc->guarded)
							continue;
						if (pc->Owns(pc_i))
						{
							P_CHAR pc_target = FindCharBySerial(pc->attacker);
							npcattacktarget(pc_i, pc_target);
							return;
						}
					}
				}
			}
			break;
		   case 30:// no idea?
		   case 50:// EV/BS
			if (!pc_i->war)
			{
				cRegion::RegionIterator4Chars ri(pc_i->pos);
				for (ri.Begin(); !ri.atEnd(); ri++)
				{
					P_CHAR pc = ri.GetData();
					if (pc != NULL)
					{
						d = chardist(pc_i, pc);
						if (d > SrvParams->attack_distance())
							continue;
						if( ( !pc->isNpc() ) && ( !online( pc ) ) )
						    continue;
						if (pc->isInvul() || pc->dead)
							continue;
						npcattacktarget(pc_i, pc);
						return;
					}
				}
			}
			break;
		case 96:
		case 60: // Skyfire - Dragon AI
			DragonAI->DoAI(pc_i, currenttime);
			break;
		default:
			clConsole.send("ERROR: cCharStuff::CheckAI-> Error npc (%8x) has invalid AI type %i\n", pc_i->serial, pc_i->npcaitype); // Morrolan
			return;
	}// switch
}// void checknpcai