示例#1
0
void cItem::explode(NXWSOCKET  s)
{
	if (s < 0 || s > now) return;	//Luxor

	unsigned int dmg=0,len=0;

	P_CHAR pc_current=MAKE_CHAR_REF(currchar[s]);
	VALIDATEPC(pc_current);

	if(!isInWorld())
		return;

	type=0; //needed for recursive explosion

	//Luxor - recursive explosions!! :DD
	NxwItemWrapper si;
	si.fillItemsNearXYZ( getPosition(), 5, true );
    for( si.rewind(); !si.isEmpty(); si++ ) {
		P_ITEM p_nearbie=si.getItem();
		if(ISVALIDPI(p_nearbie) && p_nearbie->type == ITYPE_POTION && p_nearbie->morey == 3) { //It's an explosion potion!
			p_nearbie->explode(s);
    	}
    }
	//End Luxor recursive explosions

	staticeffect2(this, 0x36, 0xB0, 0x10, 0x80, 0x00);
	soundeffect3(this, 0x0207);

	len=morex/250; //4 square max damage at 100 alchemy
	switch (morez)
	{
		case 1:dmg=RandomNum( 5,10) ;break;
		case 2:dmg=RandomNum(10,20) ;break;
		case 3:dmg=RandomNum(20,40) ;break;
		default:
			ErrOut("Switch fallout. NoX-Wizard.cpp, explodeitem()\n"); //Morrolan
			dmg=RandomNum(5,10);
	}

	if (dmg<5) dmg=RandomNum(5,10);	// 5 points minimum damage
	if (len<2) len=2;	// 2 square min damage range

	NxwCharWrapper sc;
	sc.fillCharsNearXYZ( getPosition(), len, true );
	for( sc.rewind(); !sc.isEmpty(); sc++ ) {

		P_CHAR pc=sc.getChar();
		if( ISVALIDPC(pc) ) {
			pc->damage( dmg+(2-pc->distFrom(this)), DAMAGE_FIRE );
		}
	}

	Delete();

}
示例#2
0
LOGICAL inbankrange(int i)
{
	P_CHAR pc=MAKE_CHAR_REF(i);
	VALIDATEPCR(pc,false);

	NxwCharWrapper sc;
	sc.fillCharsNearXYZ( pc->getPosition(), 6, true, false );
	for( sc.rewind(); !sc.isEmpty(); sc++ ) {
		P_CHAR pcm=sc.getChar();
	
		if (ISVALIDPC(pcm) && pcm->npcaitype==NPCAI_BANKER)
		{
			return true;
		}
	}
	return false;
}
示例#3
0
/*!
\todo backport into cChar
*/
void callguards( pChar caller )
{
	if ( !caller )
		return;

	if( !(region[caller->region].priv&0x01 ) || !SrvParms->guardsactive || !TIMEOUT( caller->antiguardstimer ) || caller->dead )
		return;

	caller->antiguardstimer=getClockmSecs()+(SECS*10);

	/*
	Sparhawk:
	1. when instant guard is set and offender nearby caller spawn guard near caller and leave attacking to checkAI
	2. when instant guard is not set and offender nearby caller walk toward caller and leave attacking to checkAI
	*/
	bool offenders = false;
	vector < pChar > guards;

	NxwCharWrapper sc;
	sc.fillCharsNearXYZ( caller->getPosition(), VISRANGE, true, false  );
	for( sc.rewind(); !sc.isEmpty(); sc++ ) {

		pChar character=sc.getChar();
		if(	! character ||
			caller == character ||
			caller->distFrom(character) > 15 ||
			character->isDead() ||
			character->isHidden() )
				continue;
			
		if ((!character->IsInnocent() || character->npcaitype == NPCAI_EVIL) && !character->IsHidden() )
			offenders = true;
		else
			if ((character->npcaitype == NPCAI_TELEPORTGUARD || character->npcaitype == NPCAI_GUARD) && !character->war && character->npcWander != cNPC::WANDER_FOLLOW)
				guards.push_back( character );
	}
	
	if ( ! offenders ) return;
	
	if ( guards.empty() && nSettings::Server::hasInstantGuards() )
	{
		pNPC guard = npcs::AddNPCxyz( caller->getSocket(), region[caller->region].guardnum[(rand()%10)+1], caller->getPosition());

		if ( guard )
		{
			guard->npcaitype=NPCAI_TELEPORTGUARD;
			guard->npcWander=cNPC::WANDER_FREELY_CIRCLE;
			guard->setNpcMoveTime();
			guard->summontimer = getClockmSecs() + SECS * 25 ;

			guard->playSFX( 0x01FE );
			staticFX(guard, 0x372A, 9, 6);

			guard->teleport();
			guard->talkAll("Don't fear, help is near", false );
		}
	}
	else
	{
		pChar guard;
		while( !guards.empty() )
		{
			guard = guards.back();
			guard->oldnpcWander = guard->npcWander;
			guard->npcWander = cNPC::WANDER_FOLLOW;
			guard->ftargserial = caller->getSerial();
			guard->antiguardstimer=getClockmSecs()+(SECS*10); // Sparhawk this should become server configurable
			guard->talkAll("Don't fear, help is on the way", false );
			//guard->antispamtimer = getClockmSecs()+SECS*5;
			guards.pop_back();
		}
	}
}
示例#4
0
void checkauto() // Check automatic/timer controlled stuff (Like fighting and regeneration)
{
//	static TIMERVAL checkspawnregions=0;
       	static TIMERVAL checktempfx=0;
	static TIMERVAL checknpcs=0;
	static TIMERVAL checktamednpcs=0;
	static TIMERVAL checknpcfollow=0;
	static TIMERVAL checkitemstime=0;
	static TIMERVAL lighttime=0;
	static TIMERVAL htmltime=0;
	static TIMERVAL housedecaytimer=0;

	LOGICAL lightChanged = false;

	//
	// Accounts
	//
	if (SrvParms->auto_a_reload > 0 && TIMEOUT( Accounts->lasttimecheck + (SrvParms->auto_a_reload*60*MY_CLOCKS_PER_SEC) ) )
		Accounts->CheckAccountFile();
	//
	// Weather (change is handled by crontab)
	//
	// Calendar
	//
	if ( TIMEOUT( uotickcount ) )
	{
		if (Calendar::advanceMinute())
			day++;
		uotickcount=uiCurrentTime+secondsperuominute*MY_CLOCKS_PER_SEC;
		if (Calendar::g_nMinute%8==0)
			moon1=(UI08)((moon1+1)%8);
		if (Calendar::g_nMinute%3==0)
			moon2=(UI08)((moon2+1)%8);
	}
	//
	// Light
	//
	if( TIMEOUT( lighttime ) )
	{
		UI08 lightLevel = worldcurlevel;

		SI32 timenow = (Calendar::g_nHour * 60) + Calendar::g_nMinute;
		SI32 dawntime = (Calendar::g_nCurDawnHour * 60) + Calendar::g_nCurDawnMin;
		SI32 sunsettime = (Calendar::g_nCurSunsetHour * 60) + Calendar::g_nCurSunsetMin;
		SI32 nighttime = qmin((sunsettime+120), (1439));
		SI32 morntime = qmax((dawntime-120), (0));
		SI32 const middaytime = 750;
//		SI32 const midnighttime = 0; // unused variable
		UI08 dawnlight = (UI08)((((worlddarklevel - worldbrightlevel))/3) + worldbrightlevel);
		//
		// default lights at dawn and sunset
		//
		if ( timenow == dawntime || timenow==sunsettime )
			lightLevel = dawnlight;
		//
		// highest light at midday
		//
		else if( timenow == middaytime )
			lightLevel = (UI08) qmax(worldbrightlevel-1, 0);
		//
		// darkest light during night
		//
		else if( timenow >= nighttime )
			lightLevel = worlddarklevel;
		//
		else if( timenow <= morntime )
			lightLevel = worlddarklevel;
		//
		// fading light slight before dawn
		//
		else if( timenow > morntime && timenow < dawntime )
			lightLevel = (UI08)linInterpolation(morntime, worlddarklevel, dawntime, dawnlight, timenow);
		//
		// fading light slight from dawn to midday
		else if( timenow > dawntime &&  timenow < middaytime )
			lightLevel = (UI08)linInterpolation(dawntime, dawnlight, middaytime, worldbrightlevel, timenow);
		//
		// fading light slight from midday to sunset
		//
		else if( timenow > middaytime && timenow < sunsettime )
			lightLevel = (UI08)linInterpolation(middaytime, worldbrightlevel, sunsettime, dawnlight, timenow);
		//
		// fading light slight from sunset to night
		//
		else if( timenow > sunsettime && timenow < nighttime )
			lightLevel = (UI08)linInterpolation(sunsettime, dawnlight, nighttime, worlddarklevel, timenow);

		if (wtype)
			lightLevel += 2;
		if (moon1+moon2<4)
			++lightLevel;
		if (moon1+moon2<10)
			++lightLevel;

		if (lightLevel != worldcurlevel)
		{
			worldcurlevel = lightLevel;
			lightChanged  = true;
		}
		lighttime=uiCurrentTime+secondsperuominute*5*MY_CLOCKS_PER_SEC;
	}

	//
	//	Housedecay and stabling
	//
	if ( TIMEOUT( housedecaytimer ) )
	{
		//////////////////////
		///// check_houses
		/////////////////////
		if( SrvParms->housedecay_secs != UINVALID )
			cHouses::check_house_decay();
		housedecaytimer = uiCurrentTime+MY_CLOCKS_PER_SEC*60*60; // check only each hour
	}
	//
	// Spawns
	//
	if( TIMEOUT( Spawns->check ) )
	{
		Spawns->doSpawn();
	}

	//
	// Shoprestock
	//
	Restocks->doRestock();

	//
	// Prison release
	//
	prison::checkForFree();

	//
	// Temporary effects
	//
	if( TIMEOUT( checktempfx ) )
		tempfx::checktempeffects();

	//
	// Characters & items
	//
	NxwSocketWrapper sw;
	sw.fillOnline();

	for( sw.rewind(); !sw.isEmpty(); sw++ )
	{
		NXWCLIENT ps = sw.getClient();
		if( ps == NULL )
			continue;

		P_CHAR pc=ps->currChar();
		if( !ISVALIDPC( pc ) )
			continue;

		if( lightChanged )
			dolight(ps->toInt(),worldcurlevel);

		pc->heartbeat();

		if( TIMEOUT( checknpcs ) || TIMEOUT( checktamednpcs ) || TIMEOUT( checknpcfollow ) )
		{
#ifdef SPAR_C_LOCATION_MAP
			PCHAR_VECTOR *pCV = pointers::getNearbyChars( pc, VISRANGE, pointers::NPC );
			PCHAR_VECTOR it( pCV->begin() ), end( pCV->end() );
			P_CHAR pNpc = 0;
			while( it != end )
			{
				pNpc = (*it);
				if( pNpc->lastNpcCheck != uiCurrentTime &&
				    (TIMEOUT( checknpcs ) ||
				    (TIMEOUT( checktamednpcs ) && pNpc->tamed) ||
				    (TIMEOUT( checknpcfollow ) && pNpc->npcWander == WANDER_FOLLOW ) ) )
				{
					pNpc->heartbeat();
					pNpc->lastNpcCheck = uiCurrentTime;
				}
				++it;
			}
#else
			NxwCharWrapper sc;
			sc.fillCharsNearXYZ( pc->getPosition(), VISRANGE, true, false );
			for( sc.rewind(); !sc.isEmpty(); sc++ )
			{
				P_CHAR npc=sc.getChar();

				if(!ISVALIDPC(npc) || !npc->npc )
					continue;

				if( npc->lastNpcCheck != uiCurrentTime &&
				    (TIMEOUT( checknpcs ) ||
				    (TIMEOUT( checktamednpcs ) && npc->tamed) ||
				    (TIMEOUT( checknpcfollow ) && npc->npcWander == WANDER_FOLLOW ) ) )
				{
					npc->heartbeat();
					npc->lastNpcCheck = uiCurrentTime;
				}
			}
#endif
		}

		if( TIMEOUT( checkitemstime ) )
		{
			NxwItemWrapper si;
			si.fillItemsNearXYZ( pc->getPosition(), 2*VISRANGE, false );
			for( si.rewind(); !si.isEmpty(); si++ )
			{
				P_ITEM pi=si.getItem();

				if( !ISVALIDPI( pi ) )
					continue;

				pi->doDecay();

				switch( pi->type )
				{
					case  51	:
					case  52	:
						//if( TIMEOUT( pi->gatetime ) )
							//for (int k=0;k<2;++k)	Sparhawk what's this???? Let's comment it out for now
							//	pi->deleteItem(); // bugfix for items disappearing
							//pi->deleteItem();
						break;
					case  61    :
					case  62	:
					case  63	:
					case  64	:
					case  65	:
					case  69	:
					case 125	:
						break; //SPAWNERS may not decay!!! --> Sparhawk then don't use the decay tag in the script
					case  88	:
						if( pi->morey >= 0 && pi->morey < 25 )
							if (pc->distFrom(pi)<=pi->morey)
								if( (UI32)RandomNum(1,100) <= pi->morez )
									soundeffect4(ps->toInt(), pi, (UI16)pi->morex);
						break;
				}
			}
		}
		// Check boats extra, or else they will only be updated every CHECK_ITEMS time
		std::map<int,P_BOAT>::iterator iter_boat;
		for ( iter_boat= s_boat.begin();iter_boat != s_boat.end();iter_boat++)
		{
			P_BOAT boat=iter_boat->second;
			P_ITEM pi=boat->getShipLink();
			if( pi->type2 == 1 || pi->type2 == 2 )
				if( TIMEOUT( pi->gatetime ) )
				{
					if (pi->type2==1)
						Boats->Move(ps->toInt(),pi->dir,pi);
					else
					{
						int dir=pi->dir+4;
						dir%=8;
						Boats->Move(ps->toInt(),dir,pi);
					}
					pi->gatetime=(TIMERVAL)(uiCurrentTime + (R64)(SrvParms->boatspeed*MY_CLOCKS_PER_SEC));

				}
		}
	}//for i<now


	if( TIMEOUT( checkitemstime ) )
		checkitemstime = (TIMERVAL)((R64) uiCurrentTime+(speed.itemtime*MY_CLOCKS_PER_SEC));
	if( TIMEOUT( checknpcs ) )
		checknpcs = (TIMERVAL)((R64) uiCurrentTime+(speed.npctime*MY_CLOCKS_PER_SEC));
	if( TIMEOUT( checktamednpcs ) )
		checktamednpcs=(TIMERVAL)((R64) uiCurrentTime+(speed.tamednpctime*MY_CLOCKS_PER_SEC));
	if( TIMEOUT( checknpcfollow ) )
		checknpcfollow=(TIMERVAL)((R64) uiCurrentTime+(speed.npcfollowtime*MY_CLOCKS_PER_SEC));
	//
	// Html
	//
	if(SrvParms->html>0 && (htmltime<=uiCurrentTime ))
	{
		updatehtml();
		htmltime=uiCurrentTime+(SrvParms->html*MY_CLOCKS_PER_SEC);
	}
	//
	// Finish
	//
	if ( TIMEOUT( nextfieldeffecttime ) )
		nextfieldeffecttime = (TIMERVAL)((R64) uiCurrentTime + (0.5*MY_CLOCKS_PER_SEC));
	if ( TIMEOUT( nextdecaytime ) )
		nextdecaytime = uiCurrentTime + (15*MY_CLOCKS_PER_SEC);
        if( TIMEOUT( checktempfx ) )
		checktempfx = (TIMERVAL)((R64) uiCurrentTime+(0.5*MY_CLOCKS_PER_SEC));
}