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(); }
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; }
/*! \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(); } } }
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)); }