void cTmpEff::Expire()
{
    int k;

    P_CHAR pc_s = FindCharBySerial(getDest());
    if (   num != 9		// grinding
            && num != 10	// create potion
            && num != 13	// door close
            && num != 14	// training dummy
            && num != 17)	// explosion
    {
        //Added by TANiS to fix errors, memory corruption and door auto-close 10-6-98
        // Check to see if it's a dead char and delete the wrong effect, or if it's just
        // a door auto-close effect and process it the right way.
        if ( pc_s == NULL )
        {
            return;		// just remove this effect
        } //End of TANiS' change
    }

    switch(num)
    {
    case 1:
        if (pc_s->priv2&0x02)
        {
            pc_s->priv2 &= 0xFD;
            int sk=calcSocketFromChar((pc_s));
            if (sk!=-1) sysmessage(sk, "You are no longer frozen.");
            Magic->afterParticles(38, pc_s);
        }
        break;
    case 2:
        pc_s->fixedlight='\xFF';
        dolight(calcSocketFromChar((pc_s)), worldbrightlevel);
        break;
    case 3:
        pc_s->chgDex(more1);
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 4:
        pc_s->in+=more1;
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 5:
        pc_s->st+=more1;
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 6:
        pc_s->chgDex(-1 * more1);
        pc_s->stm=min(pc_s->stm, (int)pc_s->effDex());
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 7:
        pc_s->in-=more1;
        pc_s->mn=min(pc_s->mn, pc_s->in);
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 8:
        pc_s->st-=more1;
        pc_s->hp=min(pc_s->hp, pc_s->st);
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 9:
        if (more1 == 0)
        {
            if (more2!=0)
            {
                sprintf((char*)temp, "*%s continues grinding.*", pc_s->name.c_str());
                npcemoteall(pc_s, (char*)temp,1);
            }
            soundeffect2(pc_s, 0x0242);
        }
        break;
    case 10:
    {
        pc_s = FindCharBySerial(getSour());
        P_ITEM pMortar = FindItemBySerial(getDest());
        if(pMortar != NULL) //AntiChrist - to prevent crashes
            Skills->CreatePotion(pc_s, more1, more2, pMortar);
    }
    break;
    case 11:
        pc_s->st-=more1;
        pc_s->hp=min(pc_s->hp, pc_s->st);
        pc_s->chgDex(-1 * more2);
        pc_s->stm=min(pc_s->stm, (int)pc_s->effDex());
        pc_s->in-=more3;
        pc_s->mn=min(pc_s->mn, pc_s->in);
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 12:
        pc_s->st+=more1;
        pc_s->chgDex(more2);
        pc_s->in+=more3;
        statwindow(calcSocketFromChar(pc_s), pc_s);
        break;
    case 13:
    {
        P_ITEM pDoor = FindItemBySerial(getDest());// door
        if (pDoor)
        {
            if (pDoor->dooropen==0)
                break;
            pDoor->dooropen=0;
            dooruse(calcSocketFromChar((pc_s)), pDoor);
        }
        break;
    }
    case 14: //- training dummies Tauriel check to see if item moved or not before searching for it
    {
        P_ITEM pTrainDummy = FindItemBySerial(getDest());
        if (pTrainDummy)
        {
            if (pTrainDummy->id()==0x1071)
            {
                pTrainDummy->setId(0x1070);
                pTrainDummy->gatetime=0;
                RefreshItem(pTrainDummy);//AntiChrist
            }
            else if (pTrainDummy->id()==0x1075)
            {
                pTrainDummy->setId(0x1074);
                pTrainDummy->gatetime=0;
                RefreshItem(pTrainDummy);//AntiChrist
            }
        }
    }
    break;
    case 15: //reactive armor
        pc_s->ra=0;
        break;
    case 16: //Explosion potion messages	Tauriel
        sprintf((char*)temp, "%i", more3);
        sysmessage(calcSocketFromChar((pc_s)), (char*)temp); // crashfix, LB
        break;
    case 17: //Explosion potion explosion	Tauriel
        pc_s = FindCharBySerial(getSour());
        explodeitem(calcSocketFromChar((pc_s)), FindItemBySerial(getDest())); //explode this item
        break;
    case 18: //Polymorph spell by AntiChrist 9/99
        if(pc_s->polymorph)//let's ensure it's under polymorph effect!
        {
            pc_s->setId(pc_s->xid);
            pc_s->polymorph=false;
            teleport(pc_s);
        }
        break;
    case 19: //Incognito spell by AntiChrist 12/99
        reverseIncognito(pc_s);
        break;

    case 20: // LSD potions, LB 5'th nov 1999
    {
        k=calcSocketFromChar((pc_s));
        if (k==-1) return;
        LSD[k]=0;
        sysmessage(k,"LSD has worn off");
        pc_s->stm=3; // stamina near 0
        pc_s->mn=3;
        pc_s->hp=pc_s->hp/7;
        impowncreate(k, pc_s, 0);
        all_items(k); // absolutely necassairy here !!!
        AllCharsIterator it;
        for (it.Begin(); !it.atEnd(); it++) // that hurts, but there's no other good way
        {
            P_CHAR pc = it.GetData();
            if (chardist( pc_s, pc ) < 15 && ( online(pc) || pc->isNpc() ) )
                updatechar(pc);
        }
    }
    break;

    case 21:
        int toDrop;
        toDrop = more1; //Effect->more1;
        if( ( pc_s->baseskill[PARRYING] - toDrop ) < 0 )
            pc_s->baseskill[PARRYING] = 0;
        else
            pc_s->baseskill[PARRYING] -= toDrop;
        break;

    case 33: // delayed hiding for gms after flamestrike effect
        k=calcSocketFromChar((pc_s));
        sysmessage(k,"You have hidden yourself well.");
        pc_s->hidden=1;
        updatechar(pc_s);
        break;

    case 34: // delayed unhide for gms
        // Changed to be uniform with delayed hideing  (Aldur)
        k = calcSocketFromChar((pc_s));
        sysmessage(k, "You are now visible.");
        pc_s->hidden = 0;
        updatechar(pc_s);
        break;

    case 35: //heals some pf - solarin
        int iHp;
        iHp=(int)more1;
        pc_s->hp+=iHp;
        updatestats(pc_s, 0);
        if (!more2)
            tempeffect(pc_s, pc_s, 35, more1+1, 1, more3, 0);
        break;

    default:
        LogErrorVar("Fallout of switch (num = %i).", num);
        break;
    }
    Items->CheckEquipment(pc_s); //AntiChrist - checks equipments for stats requirements
}
bool cAllTmpEff::Add(P_CHAR pc_source, P_CHAR pc_dest, int num, unsigned char more1, unsigned char more2, unsigned char more3, short dur)
{
    unsigned int ic; // antichrist' changes
    int color, color1, color2, socket; //used for incognito spell
    int	loopexit=0;

    if ( pc_source == NULL || pc_dest == NULL )
        return false;

    if (teffectcount>=cmem*5)
        return false;

    cTmpEff *pTE;
    for (ic=0; ic<teffectcount; ic++)	// If there is already an effect of the same or similar kind, reverse it first (Duke)
    {
        pTE = &teffects[ic];
        if (pTE->getDest() == pc_dest->serial)
        {
            if ((pTE->num==3 && num==3)||
                    (pTE->num==4 && num==4)||
                    (pTE->num==5 && num==5)||
                    (pTE->num==6 && num==6)||
                    (pTE->num==7 && num==7)||
                    (pTE->num==8 && num==8)||
                    (pTE->num==11&& num==11)||
                    (pTE->num==12&& num==12)||
                    (pTE->num==18&& num==18)|| //added Poly reverse - AntiChrist (9/99)
                    (pTE->num==21&& num==21)||
                    (pTE->num==19&& num==19)|| //added Incognito reverse - AntiChrist (12/99)
                    (pTE->num==18&& num==19)|| //reverse poly effect if we have to use incognito - AntiChrist (12/99)
                    (pTE->num==19&& num==18) )  //reverse incognito effect if we have to use poly - AntiChrist (12/99)
            {
                pTE->Reverse();
                AllTmpEff->Remove(pTE);
            }
        }
    }

    pTE=new cTmpEff;
    pTE->Init();
    pTE->setSour(pc_source->serial);
    pTE->setDest(pc_dest->serial);
    pTE->num=num;

    switch (num)
    {
    case 1:
        pc_dest->priv2 |= 0x02;
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/100);
        pTE->more1=0;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 2:	// night sight
        pc_dest->fixedlight=worldbrightlevel;
        dolight(calcSocketFromChar((pc_dest)), worldbrightlevel);
        Magic->afterParticles(6, pc_dest); // shows particles for UO:3D clients, like On OSI servers

        if(dur > 0)		// if a duration is given (potions), use that (Duke, 30.12.2000)
            pTE->setExpiretime_s(dur);
        else
            pTE->setExpiretime_s(pc_source->skill[MAGERY]*10);
        pTE->more1=0;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 3:
        if (pc_dest->effDex()<more1)
            more1=pc_dest->effDex();
        pc_dest->chgDex(-1 * more1);
        pc_dest->stm=min(pc_dest->stm, (int)pc_dest->effDex());
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 4:
        if (pc_dest->in<more1)
            more1=pc_dest->in;
        pc_dest->in-=more1;
        pc_dest->mn=min(pc_dest->mn, pc_dest->in);
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 5:
        if (pc_dest->st<more1)
            more1=pc_dest->st;
        pc_dest->st-=more1;
        pc_dest->hp=min(pc_dest->hp, pc_dest->st);
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 6:
        if (pc_dest->effDex()+more1>250)
            more1=250-pc_dest->effDex();
        pc_dest->chgDex(more1);
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        if(dur > 0)		// if a duration is given (potions), use that (Duke, 31.10.2000)
            pTE->setExpiretime_s(dur);
        else
            pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 7:
        if (pc_dest->in+more1>255)
            more1=pc_dest->in-255;
        pc_dest->in+=more1;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 8:
        if (pc_dest->st+more1>255)
            more1=pc_dest->st-255;
        pc_dest->st+=more1;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        if(dur > 0)		// if a duration is given (potions), use that (Duke, 31.10.2000)
            pTE->setExpiretime_s(dur);
        else			// else use caster's skill
            pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=0;
        pTE->dispellable=1;
        break;
    case 9:
        pTE->setExpiretime_s(more2);
        pTE->more1=more1;
        pTE->more2=more2;
        break;
    case 10:
        pTE->setExpiretime_s(12);
        pTE->more1=more1;
        pTE->more2=more2;
        break;
    case 11: // Bless
        if (pc_dest->st+more1>255)
            more1=pc_dest->st-255;
        if (pc_dest->effDex()+more2>250)
            more2=250-pc_dest->effDex();
        if (pc_dest->in+more3>255)
            more3=pc_dest->in-255;
        pc_dest->st+=more1;
        pc_dest->chgDex(more2);
        pc_dest->in+=more3;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=more2;
        pTE->more3=more3;
        pTE->dispellable=1;
        break;
    case 12: // Curse
        if (pc_dest->st<more1)
            more1=pc_dest->st;
        if (pc_dest->effDex()<more2)
            more2=pc_dest->effDex();
        if (pc_dest->in<more3)
            more3=pc_dest->in;
        pc_dest->st-=more1;
        pc_dest->chgDex(-1 * more2);
        pc_dest->in-=more3;
        statwindow(calcSocketFromChar(pc_dest), pc_dest);
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->more1=more1;
        pTE->more2=more2;
        pTE->more3=more3;
        pTE->dispellable=1;
        break;
    case 15: // Reactive armor
        pTE->setExpiretime_s(pc_source->skill[MAGERY]/10);
        pTE->dispellable=1;
        break;
    case 16: //Explosion potions	Tauriel
        pTE->setExpiretime_s(more2);
        pTE->more1=more1; //item/potion
        pTE->more2=more2; //seconds
        pTE->more3=more3; //countdown#
        break;
    case 18: //Polymorph - AntiChrist 09/99
        pTE->setExpiretime_s(polyduration);

        int c1,b,k;
        //Grey flag when polymorphed - AntiChrist (9/99)
        pc_dest->crimflag=(polyduration*MY_CLOCKS_PER_SEC)+uiCurrentTime;
        if(pc_dest->onhorse)
            k = unmounthorse(calcSocketFromChar(pc_dest));
        k=(more1<<8)+more2;

        pc_dest->xid = pc_dest->id();//let's backup previous id

        if (k>=0x000 && k<=0x3e1) // lord binary, body-values >0x3e crash the client
        {
            pc_dest->id1=k>>8; // allow only non crashing ones
            pc_dest->id2=k%256;

            c1 = pc_dest->skin; // transparency for monsters allowed, not for players,
            // if polymorphing from monster to player we have to switch from transparent to semi-transparent
            b=c1&0x4000;
            if (b==16384 && (k >=0x0190 && k<=0x03e1))
            {
                if (c1!=0x8000)
                {
                    pc_dest->skin = pc_dest->xskin = 0xF000;
                }
            }
        }
        pc_dest->polymorph=true;
        break;
    case 19://incognito spell - AntiChrist (10/99)//revised by AntiChrist - 9/12/99
    {
        pTE->setExpiretime_s(90);

        //AntiChrist 11/11/99
        //If char is already under polymorph effect, let's reverse the
        //polymorph effect to avoid problems
        if(pc_dest->polymorph)
        {
            pc_dest->setId(pc_dest->xid);
            pc_dest->polymorph=false;
            teleport(pc_dest);
        }
        int j;

        //first: let's search for beard and hair serial
        //(we could use alredy saved serials...but it's better
        //to recalculate them)
        pc_dest->hairserial=-1;
        pc_dest->beardserial=-1;

        P_ITEM pi;
        unsigned int ci;
        vector<SERIAL> vecContainer = contsp.getData(pc_dest->serial);
        for ( ci = 0; ci < vecContainer.size(); ci++)
        {
            pi = FindItemBySerial(vecContainer[ci]);
            if(pi->layer==0x10)//beard
                pc_dest->beardserial=pi->serial;
            if(pi->layer==0x0B)//hairs
                pc_dest->hairserial=pi->serial;
        }
        // ------ SEX ------
        pc_dest->xid = pc_dest->id();
        pc_dest->id1=0x01;
        //if we already have a beard..can't turn to female
        if(pc_dest->beardserial>-1)
        {   //if character has a beard...only male
            pc_dest->id2='\x90';//male
        } else
        {   //if no beard let's randomly change
            if((rand()%2)==0) pc_dest->id2='\x90';//male
            else pc_dest->id2='\x91';//or female
        }

        // --- SKINCOLOR ---
        pc_dest->xskin = pc_dest->skin;
        color=rand()%6;
        switch(color)
        {
        case 0:
            pc_dest->skin = 0x83EA;
            break;
        case 1:
            pc_dest->skin = 0x8405;
            break;
        case 2:
            pc_dest->skin = 0x83EF;
            break;
        case 3:
            pc_dest->skin = 0x83F5;
            break;
        case 4:
            pc_dest->skin = 0x841C;
            break;
        case 5:
            pc_dest->skin = 0x83FB;
            break;
        default:
            break;
        }

        // ------ NAME -----
        pc_dest->orgname = pc_dest->name;

        if(pc_dest->id2==0x90)
            setrandomname(pc_dest, "1");//get a name from male list
        else
            setrandomname(pc_dest, "2");//get a name from female list

        //
        //damn..this formula seems to include also some bad color...
        //i'll test this later
        //AntiChrist
        //
        //use unique color for hair&beard
        //color=0x044E+(rand()%(0x04AD-0x044E));

        //i had to track down some valid value
        //for hair/beard colors, cause that
        //formula contained some bad value =(
        //but now it works perfectly :)
        //AntiChrist-11/11/99
        color=rand()%8;
        switch(color)
        {
        case 0:
            color=0x044e;
            break;
        case 1:
            color=0x0455;
            break;
        case 2:
            color=0x045e;
            break;
        case 3:
            color=0x0466;
            break;
        case 4:
            color=0x046a;
            break;
        case 5:
            color=0x0476;
            break;
        case 6:
            color=0x0473;
            break;
        case 7:
            color=0x047c;
            break;
        default://it should not go here...but..who nows =P
            color=0x044e;
        }
        color1=color>>8;
        color2=color%256;

        // ------ HAIR -----
        if(pc_dest->hairserial>-1)//if hairs exist
        {   //change hair style/color
            P_ITEM pHair = FindItemBySerial(pc_dest->hairserial);
            if(pHair)
            {
                //stores old hair values...
                pHair->moreb1 = static_cast<unsigned char>(pHair->color>>8);
                pHair->moreb2 = static_cast<unsigned char>(pHair->color%256);
                pHair->moreb3=pHair->id1;
                pHair->moreb4=pHair->id2;

                //and change them with random ones
                switch(rand()%10)
                {
                case 0:
                    pHair->id2='\x3B';
                    break;
                case 1:
                    pHair->id2='\x3C';
                    break;
                case 2:
                    pHair->id2='\x3D';
                    break;
                case 3:
                    pHair->id2='\x44';
                    break;
                case 4:
                    pHair->id2='\x45';
                    break;
                case 5:
                    pHair->id2='\x46';
                    break;
                case 6:
                    pHair->id2='\x47';
                    break;
                case 7:
                    pHair->id2='\x48';
                    break;
                case 8:
                    pHair->id2='\x49';
                    break;
                case 9:
                    pHair->id2='\x4A';
                    break;
                default:
                    pHair->id2='\x4A';
                    break;
                }

                //random color
                pHair->color = color;
                //let's check for invalid values
                if ( pHair->color < 0x044E || pHair->color > 0x04AD )
                {
                    pHair->color = 0x044E;
                }

                pHair->incognito = true;//AntiChrist
            }//if j!=-1
        }//if hairserial!=-1


        // -------- BEARD --------
        if(pc_dest->id2==0x90)// only if a man
            if(pc_dest->beardserial>-1)//if beard exist
            {   //change beard style/color
                P_ITEM pBeard = FindItemBySerial(pc_dest->beardserial);
                if(pBeard)
                {
                    //clConsole.send("BEARD FOUND!!\n");
                    //stores old beard values
                    pBeard->moreb1 = static_cast<unsigned char>(pBeard->color>>8);
                    pBeard->moreb2 = static_cast<unsigned char>(pBeard->color%256);
                    pBeard->moreb3 = static_cast<unsigned char>(pBeard->id() >> 8);
                    pBeard->moreb4 = static_cast<unsigned char>(pBeard->id()%256);

                    //changes them with random ones
                    switch(rand()%7)
                    {
                    case 0:
                        pBeard->id2='\x3E';
                        break;
                    case 1:
                        pBeard->id2='\x3F';
                        break;
                    case 2:
                        pBeard->id2='\x40';
                        break;
                    case 3:
                        pBeard->id2='\x41';
                        break;
                    case 4:
                        pBeard->id2='\x4B';
                        break;
                    case 5:
                        pBeard->id2='\x4C';
                        break;
                    case 6:
                        pBeard->id2='\x4D';
                        break;
                    default:
                        pBeard->id2='\x4D';
                        break;
                    }

                    //random color
                    pBeard->color = color;

                    if ( pBeard->color < 0x044E || pBeard->color > 0x04AD )
                    {
                        pBeard->color = 0x044E;
                    }

                    pBeard->incognito=true;//AntiChrist
                }//if j!=-1
            }//if beardserial!=-1
Beispiel #3
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));
}