//s: char# void cCombat::SpawnGuard(P_CHAR pc_offender, P_CHAR pc_caller, int x, int y, signed char z) { int t; // if (i < 0 || i >= cmem || s < 0 || s >= cmem) // return; // P_CHAR pc_offender = MAKE_CHARREF_LR(s); // P_CHAR pc_caller = MAKE_CHARREF_LR(i); if ( pc_offender == NULL || pc_caller == NULL) return; if (!(pc_caller->inGuardedArea() || pc_offender->inGuardedArea())) return; if (pc_offender->dead || pc_caller->dead) return; // AntiChrist if (SrvParams->guardsActive() && !pc_offender->isInvul()) { t = region[pc_caller->region].guardnum[(rand()%10)]; P_CHAR pc_guard = Npcs->AddNPCxyz(calcSocketFromChar(pc_offender), t, 0, x, y, z); if ( pc_guard == NULL ) return; pc_guard->npcaitype = 4; // CITY GUARD, LB, bugfix, was 0x40 -> not existing pc_guard->setAttackFirst(); pc_guard->attacker = pc_offender->serial; pc_guard->targ = pc_offender->serial; pc_guard->npcWander = 2; // set wander mode Tauriel npcToggleCombat(pc_guard); pc_guard->setNextMoveTime(); pc_guard->summontimer =(getNormalizedTime() +(MY_CLOCKS_PER_SEC*25)); soundeffect2(pc_guard, 0x01FE); // Tauriel 1-9-99 changed to stop crashing used to call soundeffect (expeted socket) staticeffect(pc_guard, 0x37, 0x2A, 0x09, 0x06); updatechar(pc_guard); switch (RandomNum(0,1)) { case 0: npctalkall(pc_guard, "Thou shalt regret thine actions, swine!", 1); break; case 1: npctalkall(pc_guard, "Death to all Evil!", 1); break; } } }
void cCombat::ItemCastSpell(UOXSOCKET s, P_CHAR pc, P_ITEM pi)//S=Socket c=Char # Target i=Item //Itemid { if(!pi) return; P_CHAR pc_currchar = currchar[s]; unsigned short int spellnum=((pi->morex*8)-8)+pi->morey; unsigned short int tempmana=pc_currchar->mn;//Save their mana so we can give it back. unsigned short int tempmage=pc_currchar->skill[MAGERY];//Easier than writing new functions for all these spells if(pi->type!=15) return; if(pi->morez<=0) return; switch(spellnum) { case 1: Magic->ClumsySpell(pc_currchar,pc); break; //LB case 3: Magic->FeebleMindSpell(pc_currchar,pc); break; //LB case 5: Magic->MagicArrow(pc_currchar,pc); break; // lB case 8: Magic->WeakenSpell(pc_currchar,pc); break; //LB case 18: Magic->FireballSpell(pc_currchar,pc); break; //LB case 22: Magic->HarmSpell(pc_currchar,pc); break; //LB case 27: Magic->CurseSpell(pc_currchar,pc); break; //LB case 30: Magic->LightningSpell(pc_currchar,pc); break; //lb case 37: Magic->MindBlastSpell(pc_currchar,pc); break; case 38: Magic->ParalyzeSpell(pc_currchar,pc); break; //lb case 42: Magic->EnergyBoltSpell(pc_currchar,pc); break; case 43: Magic->ExplosionSpell(pc_currchar,pc); break; case 51: Magic->FlameStrikeSpell(pc_currchar,pc); break; default: staticeffect(pc_currchar, 0x37, 0x35, 0, 30); soundeffect2(pc_currchar, 0x005C); break; } pc_currchar->mn+=tempmana; pc_currchar->skill[MAGERY]=tempmage; if(pc_currchar->in<pc_currchar->mn) pc_currchar->mn=pc_currchar->in;//Shouldn't happen, but just in case; updatestats(pc_currchar, 1); pi->morez--; if(pi->morez==0)//JUST lost it's charge.... sysmessage(s, tr("This item is out of charges.")); }
void deadattack (NXWSOCKET s, CHARACTER i) { CHARACTER cc = currchar[s]; P_CHAR pc = MAKE_CHAR_REF( cc ); VALIDATEPC( pc ); P_CHAR pc_other = MAKE_CHAR_REF( i ); VALIDATEPC( pc_other ); if(pc_other->npc) { if(pc_other->npcaitype==NPCAI_HEALER) { if( pc->IsInnocent() ) { if ( pc->distFrom( pc_other ) <= 3 ) {//let's resurrect him! pc_other->playAction(0x10); pc->resurrect(); staticeffect(cc, 0x37, 0x6A, 0x09, 0x06); switch(RandomNum(0, 4)) { case 0: pc_other->talkAll( TRANSLATE("Thou art dead, but 'tis within my power to resurrect thee. Live!"),0); break; case 1: pc_other->talkAll( TRANSLATE("Allow me to resurrect thee ghost. Thy time of true death has not yet come."),0); break; case 2: pc_other->talkAll( TRANSLATE("Perhaps thou shouldst be more careful. Here, I shall resurrect thee."),0); break; case 3: pc_other->talkAll( TRANSLATE("Live again, ghost! Thy time in this world is not yet done."),0); break; case 4: pc_other->talkAll( TRANSLATE("I shall attempt to resurrect thee."),0); break; } } else {//if dist>3 pc_other->talkAll( TRANSLATE("Come nearer, ghost, and i'll give you life!"),1); } } else {//if a bad guy pc_other->talkAll( TRANSLATE("I will not give life to a scoundrel like thee!"),1); } } else if( pc_other->npcaitype == NPCAI_EVILHEALER ) { if( pc->IsMurderer()) { if ( pc->distFrom( pc_other ) <=3 ) {//let's resurrect him! pc_other->playAction(0x10); pc->resurrect(); staticeffect(cc, 0x37, 0x09, 0x09, 0x19); //Flamestrike effect switch(rand()%5) { case 0: pc_other->talkAll( TRANSLATE("Fellow minion of Mondain, Live!!"),0); break; case 1: pc_other->talkAll( TRANSLATE("Thou has evil flowing through your vains, so I will bring you back to life."),0); break; case 2: pc_other->talkAll( TRANSLATE("If I res thee, promise to raise more hell!."),0); break; case 3: pc_other->talkAll( TRANSLATE("From hell to Britannia, come alive!."),0); break; case 4: pc_other->talkAll( TRANSLATE("Since you are Evil, I will bring you back to consciouness."),0); break; } } else {//if dist >3 pc_other->talkAll( TRANSLATE("Come nearer, evil soul, and i'll give you life!"),1); } } else {//if player is a good guy pc_other->talkAll( TRANSLATE("I dispise all things good. I shall not give thee another chance!"),1); } } else { sysmessage(s,TRANSLATE("You are dead and cannot do that.")); }//npcaitype check } else {//if this not a npc but a player if(SrvParms->persecute) {//start persecute stuff - AntiChrist pc->targserial = pc_other->getSerial32(); Skills::Persecute(s); } else { sysmessage(s,TRANSLATE("You are dead and cannot do that.")); } }//if npc }
void dump_item(P_CLIENT ps, PKGx08 *pp) // Item is dropped on ground or a character { // tile_st tile; UOXSOCKET s=ps->GetSocket(); CHARACTER cc=ps->GetCurrChar(); P_CHAR pc_currchar = MAKE_CHARREF_LR(cc); P_ITEM pi=FindItemBySerial(pp->Iserial); if (!pi) { LogErrorVar("client sent bad itemserial %d",pp->Iserial); return; } Weight->NewCalc(DEREF_P_CHAR(pc_currchar)); statwindow(s,DEREF_P_CHAR(pc_currchar)); pi->flags.isBeeingDragged=false; //Ripper...so order/chaos shields disappear when on ground. if( pi->id1 == 0x1B && ( pi->id2 == 0xC3 || pi->id2 == 0xC4 ) ) { soundeffect2(DEREF_P_CHAR(pc_currchar), 0x01, 0xFE); staticeffect(DEREF_P_CHAR(pc_currchar), 0x37, 0x2A, 0x09, 0x06); Items->DeleItem( pi ); return; } //test UOP blocking Tauriel 1-12-99 if (!pi->isInWorld()) { item_bounce6(ps,pi); return; } if (!pc_currchar->canPickUp(pi)) { item_bounce6(ps,pi); return; } if (buffer[s][5]!=(unsigned char)'\xFF') { pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc); pi->SetContSerial(-1); if (pi->glow) { pc_currchar->removeHalo(pi); pc_currchar->glowHalo(pi); } SndRemoveitem(pi->serial); RefreshItem(pi); } else { ItemDroppedOnChar(ps, pp, pi); Weight->NewCalc(DEREF_P_CHAR(pc_currchar)); // Ison 2-20-99 statwindow(s,DEREF_P_CHAR(pc_currchar)); itemsfx(s, pi->id()); // Dupois - see itemsfx() for details// Added Oct 09, 1998 //Boats ! if (pc_currchar->multis>0) //How can they put an item in a multi if they aren't in one themselves Cut lag by not checking everytime something is put down { P_ITEM pi_multi = FindItemBySerial( pc_currchar->multis ); if (pi_multi != NULL) { pi_multi = findmulti(pi->pos); if (pi_multi != NULL) pi->SetMultiSerial(pi_multi->serial); } } //End Bots } }
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
void advancementobjects(int s, int x, int allways) { char sect[512]; unsigned long loopexit=0; P_CHAR pc_s = MAKE_CHARREF_LR(s); int pos; if ((pc_s->advobj==0)||(allways==1)) { staticeffect(s, 0x37, 0x3A, 0, 15); soundeffect2(s, 0x01, 0xE9); pc_s->advobj=x; openscript("advance.scp"); sprintf(sect, "ADVANCEMENT %i", x); if (!i_scripts[advance_script]->find(sect)) { closescript(); clConsole.send("ADVANCEMENT OBJECT: Script section not found. Aborting.\n"); pc_s->advobj=0; return; } else do { read2(); if (script1[0]!='}') { if ((!(strcmp("STR",(char*)script1)))||(!(strcmp("STRENGTH",(char*)script1)))) { pc_s->st= getstatskillvalue((char*)script2); pc_s->st2 = pc_s->st; } if ((!(strcmp("DEX",(char*)script1)))||(!(strcmp("DEXTERITY",(char*)script1)))) { pc_s->setDex(getstatskillvalue((char*)script2)); } if ((!(strcmp("INT",(char*)script1)))||(!(strcmp("INTELLIGENCE",(char*)script1)))) { pc_s->in= getstatskillvalue((char*)script2); pc_s->in2 = pc_s->in; } if ((!(strcmp("ALCHEMY",(char*)script1)))||(!(strcmp("SKILL0",(char*)script1)))) pc_s->baseskill[ALCHEMY] = getstatskillvalue((char*)script2); if ((!(strcmp("ANATOMY",(char*)script1)))||(!(strcmp("SKILL1",(char*)script1)))) pc_s->baseskill[ANATOMY] = getstatskillvalue((char*)script2); if ((!(strcmp("ANIMALLORE",(char*)script1)))||(!(strcmp("SKILL2",(char*)script1)))) pc_s->baseskill[ANIMALLORE] = getstatskillvalue((char*)script2); if ((!(strcmp("ITEMID",(char*)script1)))||(!(strcmp("SKILL3",(char*)script1)))) pc_s->baseskill[ITEMID] = getstatskillvalue((char*)script2); if ((!(strcmp("ARMSLORE",(char*)script1)))||(!(strcmp("SKILL4",(char*)script1)))) pc_s->baseskill[ARMSLORE] = getstatskillvalue((char*)script2); if ((!(strcmp("PARRYING",(char*)script1)))||(!(strcmp("SKILL5",(char*)script1)))) pc_s->baseskill[PARRYING] = getstatskillvalue((char*)script2); if ((!(strcmp("BEGGING",(char*)script1)))||(!(strcmp("SKILL6",(char*)script1)))) pc_s->baseskill[BEGGING] = getstatskillvalue((char*)script2); if ((!(strcmp("BLACKSMITHING",(char*)script1)))||(!(strcmp("SKILL7",(char*)script1)))) pc_s->baseskill[BLACKSMITHING] = getstatskillvalue((char*)script2); if ((!(strcmp("BOWCRAFT",(char*)script1)))||(!(strcmp("SKILL8",(char*)script1)))) pc_s->baseskill[BOWCRAFT] = getstatskillvalue((char*)script2); if ((!(strcmp("PEACEMAKING",(char*)script1)))||(!(strcmp("SKILL9",(char*)script1)))) pc_s->baseskill[PEACEMAKING] = getstatskillvalue((char*)script2); if ((!(strcmp("CAMPING",(char*)script1)))||(!(strcmp("SKILL10",(char*)script1)))) pc_s->baseskill[CAMPING] = getstatskillvalue((char*)script2); if ((!(strcmp("CARPENTRY",(char*)script1)))||(!(strcmp("SKILL11",(char*)script1)))) pc_s->baseskill[CARPENTRY] = getstatskillvalue((char*)script2); if ((!(strcmp("CARTOGRAPHY",(char*)script1)))||(!(strcmp("SKILL12",(char*)script1)))) pc_s->baseskill[CARTOGRAPHY] = getstatskillvalue((char*)script2); if ((!(strcmp("COOKING",(char*)script1)))||(!(strcmp("SKILL13",(char*)script1)))) pc_s->baseskill[COOKING] = getstatskillvalue((char*)script2); if ((!(strcmp("DETECTINGHIDDEN",(char*)script1)))||(!(strcmp("SKILL14",(char*)script1)))) pc_s->baseskill[DETECTINGHIDDEN] = getstatskillvalue((char*)script2); if ((!(strcmp("ENTICEMENT",(char*)script1)))||(!(strcmp("SKILL15",(char*)script1)))) pc_s->baseskill[ENTICEMENT] = getstatskillvalue((char*)script2); if ((!(strcmp("EVALUATINGINTEL",(char*)script1)))||(!(strcmp("SKILL16",(char*)script1)))) pc_s->baseskill[EVALUATINGINTEL] = getstatskillvalue((char*)script2); if ((!(strcmp("HEALING",(char*)script1)))||(!(strcmp("SKILL17",(char*)script1)))) pc_s->baseskill[HEALING] = getstatskillvalue((char*)script2); if ((!(strcmp("FISHING",(char*)script1)))||(!(strcmp("SKILL18",(char*)script1)))) pc_s->baseskill[FISHING] = getstatskillvalue((char*)script2); if ((!(strcmp("FORENSICS",(char*)script1)))||(!(strcmp("SKILL19",(char*)script1)))) pc_s->baseskill[FORENSICS] = getstatskillvalue((char*)script2); if ((!(strcmp("HERDING",(char*)script1)))||(!(strcmp("SKILL20",(char*)script1)))) pc_s->baseskill[HERDING] = getstatskillvalue((char*)script2); if ((!(strcmp("HIDING",(char*)script1)))||(!(strcmp("SKILL21",(char*)script1)))) pc_s->baseskill[HIDING] = getstatskillvalue((char*)script2); if ((!(strcmp("PROVOCATION",(char*)script1)))||(!(strcmp("SKILL22",(char*)script1)))) pc_s->baseskill[PROVOCATION] = getstatskillvalue((char*)script2); if ((!(strcmp("INSCRIPTION",(char*)script1)))||(!(strcmp("SKILL23",(char*)script1)))) pc_s->baseskill[INSCRIPTION] = getstatskillvalue((char*)script2); if ((!(strcmp("LOCKPICKING",(char*)script1)))||(!(strcmp("SKILL24",(char*)script1)))) pc_s->baseskill[LOCKPICKING] = getstatskillvalue((char*)script2); if ((!(strcmp("MAGERY",(char*)script1)))||(!(strcmp("SKILL25",(char*)script1)))) pc_s->baseskill[MAGERY] = getstatskillvalue((char*)script2); if ((!(strcmp("MAGICRESISTANCE",(char*)script1)))||(!(strcmp("RESIST",(char*)script1)))||(!(strcmp("SKILL26",(char*)script1)))) pc_s->baseskill[MAGICRESISTANCE] = getstatskillvalue((char*)script2); if ((!(strcmp("TACTICS",(char*)script1)))||(!(strcmp("SKILL27",(char*)script1)))) pc_s->baseskill[TACTICS] = getstatskillvalue((char*)script2); if ((!(strcmp("SNOOPING",(char*)script1)))||(!(strcmp("SKILL28",(char*)script1)))) pc_s->baseskill[SNOOPING] = getstatskillvalue((char*)script2); if ((!(strcmp("MUSICIANSHIP",(char*)script1)))||(!(strcmp("SKILL29",(char*)script1)))) pc_s->baseskill[MUSICIANSHIP] = getstatskillvalue((char*)script2); if ((!(strcmp("POISONING",(char*)script1)))||(!(strcmp("SKILL30",(char*)script1)))) pc_s->baseskill[POISONING] = getstatskillvalue((char*)script2); if ((!(strcmp("ARCHERY",(char*)script1)))||(!(strcmp("SKILL31",(char*)script1)))) pc_s->baseskill[ARCHERY] = getstatskillvalue((char*)script2); if ((!(strcmp("SPIRITSPEAK",(char*)script1)))||(!(strcmp("SKILL32",(char*)script1)))) pc_s->baseskill[SPIRITSPEAK] = getstatskillvalue((char*)script2); if ((!(strcmp("STEALING",(char*)script1)))||(!(strcmp("SKILL33",(char*)script1)))) pc_s->baseskill[STEALING] = getstatskillvalue((char*)script2); if ((!(strcmp("TAILORING",(char*)script1)))||(!(strcmp("SKILL34",(char*)script1)))) pc_s->baseskill[TAILORING] = getstatskillvalue((char*)script2); if ((!(strcmp("TAMING",(char*)script1)))||(!(strcmp("SKILL35",(char*)script1)))) pc_s->baseskill[TAMING] = getstatskillvalue((char*)script2); if ((!(strcmp("TASTEID",(char*)script1)))||(!(strcmp("SKILL36",(char*)script1)))) pc_s->baseskill[TASTEID] = getstatskillvalue((char*)script2); if ((!(strcmp("TINKERING",(char*)script1)))||(!(strcmp("SKILL37",(char*)script1)))) pc_s->baseskill[TINKERING] = getstatskillvalue((char*)script2); if ((!(strcmp("TRACKING",(char*)script1)))||(!(strcmp("SKILL38",(char*)script1)))) pc_s->baseskill[TRACKING] = getstatskillvalue((char*)script2); if ((!(strcmp("VETERINARY",(char*)script1)))||(!(strcmp("SKILL39",(char*)script1)))) pc_s->baseskill[VETERINARY] = getstatskillvalue((char*)script2); if ((!(strcmp("SWORDSMANSHIP",(char*)script1)))||(!(strcmp("SKILL40",(char*)script1)))) pc_s->baseskill[SWORDSMANSHIP] = getstatskillvalue((char*)script2); if ((!(strcmp("MACEFIGHTING",(char*)script1)))||(!(strcmp("SKILL41",(char*)script1)))) pc_s->baseskill[MACEFIGHTING] = getstatskillvalue((char*)script2); if ((!(strcmp("FENCING",(char*)script1)))||(!(strcmp("SKILL42",(char*)script1)))) pc_s->baseskill[FENCING] = getstatskillvalue((char*)script2); if ((!(strcmp("WRESTLING",(char*)script1)))||(!(strcmp("SKILL43",(char*)script1)))) pc_s->baseskill[WRESTLING] = getstatskillvalue((char*)script2); if ((!(strcmp("LUMBERJACKING",(char*)script1)))||(!(strcmp("SKILL44",(char*)script1)))) pc_s->baseskill[LUMBERJACKING] = getstatskillvalue((char*)script2); if ((!(strcmp("MINING",(char*)script1)))||(!(strcmp("SKILL45",(char*)script1)))) pc_s->baseskill[MINING] = getstatskillvalue((char*)script2); // lb, new skills if ((!(strcmp("MEDITATION",(char*)script1)))||(!(strcmp("SKILL46",(char*)script1)))) pc_s->baseskill[MEDITATION] = getstatskillvalue((char*)script2); if ((!(strcmp("STEALTH",(char*)script1)))||(!(strcmp("SKILL47",(char*)script1)))) pc_s->baseskill[STEALTH] = getstatskillvalue((char*)script2); if ((!(strcmp("REMOVETRAPS",(char*)script1)))||(!(strcmp("SKILL48",(char*)script1)))) pc_s->baseskill[REMOVETRAPS] = getstatskillvalue((char*)script2); if ((!(strcmp("DYEHAIR",(char*)script1)))) { unsigned int ci; vector<SERIAL> vecContainer = contsp.getData(pc_s->serial); P_ITEM pi_hair = NULL; for (ci = 0; ci < vecContainer.size(); ci++) { P_ITEM pi_temp = FindItemBySerial(vecContainer[ci]); if (pi_temp != NULL) if (pi_temp->layer == 0x0B) { pi_hair = pi_temp; break; } } if (pi_hair != NULL) { x=hex2num(script2); pi_hair->color1=x>>8; pi_hair->color2=x%256; RefreshItem(pi_hair);//AntiChrist teleport(DEREF_P_CHAR(pc_s)); } } if ((!(strcmp("DYEBEARD",(char*)script1)))) { int ci; P_ITEM pi_beard = NULL; vector<SERIAL> vecContainer = contsp.getData(pc_s->serial); for (ci = 0; ci < vecContainer.size();ci++) { P_ITEM pi_temp = FindItemBySerial(vecContainer[ci]); if (pi_temp != NULL) if (pi_temp->layer == 0x10) { pi_beard = pi_temp; break; } } if (pi_beard != NULL) { x=hex2num(script2); pi_beard->color1=x>>8; pi_beard->color2=x%256; RefreshItem(pi_beard);//AntiChrist teleport(DEREF_P_CHAR(pc_s)); }
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
void dump_item(NXWCLIENT ps, PKGx08 *pp) // Item is dropped on ground or a character { if (ps == NULL) return; tile_st tile; NXWSOCKET s=ps->toInt(); P_CHAR pc=ps->currChar(); VALIDATEPC(pc); P_ITEM pi=pointers::findItemBySerial(pp->Iserial); if (!ISVALIDPI(pi)) { LogError("client sent bad itemserial %d",pp->Iserial); return; } if ( isCharSerial(pi->getContSerial()) && pi->getContSerial() != pc->getSerial32() ) { P_CHAR pc_i = pointers::findCharBySerial(pi->getContSerial()); if (ISVALIDPC(pc_i)) pc_i->sysmsg("Warning, backpack disappearing bug located!"); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); } if (pi->magic == 2) { //Luxor -- not movable objects if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->MoveTo( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } if(pi!=NULL) { weights::NewCalc(pc); statwindow(pc,pc); } //Ripper...so order/chaos shields disappear when on ground. if( pi->getId()==0x1BC3 || pi->getId()==0x1BC4 ) { pc->playSFX( 0x01FE); staticeffect(DEREF_P_CHAR(pc), 0x37, 0x2A, 0x09, 0x06); pi->Delete(); return; } //test UOP blocking Tauriel 1-12-99 if (!pi->isInWorld()) { item_bounce6(ps,pi); return; } data::seekTile(pi->getId(), tile); if (!pc->IsGM() && ((pi->magic==2 || (tile.weight==255 && pi->magic!=1))&&!pc->canAllMove()) || ( (pi->magic==3 || pi->magic==4) && !(pi->getOwnerSerial32()==pc->getSerial32()))) { item_bounce6(ps,pi); return; } if (buffer[s][5]!=(unsigned char)'\xFF') { if (pi->amxevents[EVENT_IDROPINLAND]!=NULL) { g_bByPass = false; pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc); pi->amxevents[EVENT_IDROPINLAND]->Call( pi->getSerial32(), pc->getSerial32() ); if (g_bByPass) { pi->Refresh(); return; } } /* //<Luxor> g_bByPass = false; pi->runAmxEvent( EVENT_IDROPINLAND, pi->getSerial32(), pc->getSerial32() ); if (g_bByPass) { pi->Refresh(); return; } //</Luxor> */ NxwSocketWrapper sw; sw.fillOnline( pi ); for( sw.rewind(); !sw.isEmpty(); sw++ ) { SendDeleteObjectPkt( sw.getSocket(), pi->getSerial32() ); } pi->MoveTo(pp->TxLoc,pp->TyLoc,pp->TzLoc); pi->setContSerial(-1); P_ITEM p_boat = Boats->GetBoat(pi->getPosition()); if(ISVALIDPI(p_boat)) { pi->SetMultiSerial(p_boat->getSerial32()); } pi->Refresh(); } else { if ( !ItemDroppedOnChar(ps, pp, pi) ) { //<Luxor>: Line of sight check //This part avoids the circle of transparency walls bug //----- if ( !lineOfSight( pc->getPosition(), Loc( pp->TxLoc, pp->TyLoc, pp->TzLoc ) ) ) { ps->sysmsg(TRANSLATE("You cannot place an item there!")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); pi->layer = pi->oldlayer; pi->Refresh(); return; } //</Luxor> //<Luxor> Items count check if (!pc->IsGM()) { NxwItemWrapper si; si.fillItemsAtXY( pp->TxLoc, pp->TyLoc ); if (si.size() >= 2) { //Only 2 items permitted ps->sysmsg(TRANSLATE("There is not enough space there!")); Sndbounce5(s); if (ps->isDragging()) { ps->resetDragging(); UpdateStatusWindow(s,pi); } if (ISVALIDPI(pc->getBackpack())) { pi->setCont(pc->getBackpack()); pi->SetRandPosInCont(pc->getBackpack()); } else { pi->setContSerial( pi->getContSerial(true) ); pi->setPosition( pi->getOldPosition() ); } pi->layer = pi->oldlayer; pi->Refresh(); return; } } //</Luxor> } weights::NewCalc(pc); // Ison 2-20-99 statwindow(pc,pc); pc->playSFX( itemsfx(pi->getId()) ); //Boats ! if (pc->getMultiSerial32() > 0) //How can they put an item in a multi if they aren't in one themselves Cut lag by not checking everytime something is put down { P_ITEM multi = pointers::findItemBySerial( pc->getMultiSerial32() ); if (ISVALIDPI(multi)) { //setserial(DEREF_P_ITEM(pi),DEREF_P_ITEM(multi),7); pi->SetMultiSerial(multi->getSerial32()); } } //End Boats } }
void cCombat::DoCombat(P_CHAR pc_attacker, unsigned int currenttime) { int x, bowtype=0;// spamanachecking, tmp; if ( pc_attacker == NULL ) return; if (pc_attacker->free) return; P_ITEM pWeapon=pc_attacker->getWeapon(); P_CHAR pc_defender = FindCharBySerial(pc_attacker->targ); /*if (pc_attacker->priv2&2) //The char is paralyzed { sysmessage(calcSocketFromChar(pc_attacker), "You are frozen and cannot attack."); return; }*/ if ((pc_defender == NULL) || (pc_defender->isPlayer() && !online(pc_defender) || pc_defender->isHidden()) && pc_attacker->war) { pc_attacker->war=false; // LB pc_attacker->timeout=0; pc_attacker->attacker = INVALID_SERIAL; pc_attacker->resetAttackFirst(); return; } if (( pc_attacker->isNpc() || online(pc_attacker) ) && pc_defender != NULL ) { if (pc_defender == NULL) return; if (pc_defender->free) return; if (pc_attacker->dispz > (pc_defender->dispz +10)) return;//FRAZAI if (pc_attacker->dispz < (pc_defender->dispz -10)) return;//FRAZAI if ((pc_defender->isNpc() && pc_defender->npcaitype!=17) || (online(pc_defender) && !pc_defender->dead) ) // ripper { if (chardist( pc_attacker, pc_defender ) > SrvParams->attack_distance()) { if (pc_attacker->npcaitype==4 && pc_attacker->inGuardedArea()) // changed from 0x40 to 4, LB { pc_attacker->moveTo(pc_defender->pos); teleport(pc_attacker); soundeffect2(pc_attacker, 0x01FE); // crashfix, LB staticeffect(pc_attacker, 0x37, 0x2A, 0x09, 0x06); npctalkall(pc_attacker,"Halt, scoundrel!",1); } else { // else -> npcaityes != 4 pc_attacker->targ = INVALID_SERIAL; pc_attacker->timeout=0; P_CHAR pc = FindCharBySerial(pc_attacker->attacker); if (pc != NULL) { pc->resetAttackFirst(); pc->attacker = INVALID_SERIAL; // lb crashfix } pc_attacker->attacker=INVALID_SERIAL; pc_attacker->resetAttackFirst(); if (pc_attacker->isNpc() && pc_attacker->npcaitype!=17 && !pc_attacker->dead && pc_attacker->war) npcToggleCombat(pc_attacker); // ripper } } else { if (pc_attacker->targ == INVALID_SERIAL) { npcsimpleattacktarget(pc_attacker, pc_defender); x=(((100-pc_attacker->effDex())*MY_CLOCKS_PER_SEC)/25)+(1*MY_CLOCKS_PER_SEC); //Yet another attempt. pc_attacker->timeout=currenttime+x; return; } if (Combat->TimerOk(pc_attacker)) { int los = line_of_sight(-1, pc_attacker->pos, pc_defender->pos, WALLS_CHIMNEYS+DOORS+FLOORS_FLAT_ROOFING); UOXSOCKET s1 = calcSocketFromChar(pc_attacker); int fightskill=Skills->GetCombatSkill(pc_attacker); x=0; if (fightskill==ARCHERY) { if (los) { int arrowsquant; bowtype=Combat->GetBowType(pc_attacker); if (bowtype==1) arrowsquant=getamount(pc_attacker, 0x0F3F); else arrowsquant=getamount(pc_attacker, 0x1BFB); if (arrowsquant>0) x=1; //else // sysmessage(s1, "You are out of ammunitions!"); //-Fraz- this message can cause problems removed } } if ( chardist( pc_attacker, pc_defender )<2 && fightskill!=ARCHERY ) x=1; if (x) { // - Do stamina maths - AntiChrist (6) - if(abs(SrvParams->attackstamina())>0 && !pc_attacker->isGM()) { if((SrvParams->attackstamina()<0)&&(pc_attacker->stm<abs(SrvParams->attackstamina()))) { sysmessage(s1, tr("You are too tired to attack.")); SetWeaponTimeout(pc_attacker, pWeapon); return; } pc_attacker->stm += SrvParams->attackstamina(); if (pc_attacker->stm>pc_attacker->effDex()) pc_attacker->stm=pc_attacker->effDex(); if (pc_attacker->stm<0) pc_attacker->stm=0; updatestats((pc_attacker),2); //LB, crashfix, was currchar[a] // --------ATTACK STAMINA END ------ } DoCombatAnimations( pc_attacker, pc_defender, fightskill, bowtype, los); if (((chardist( pc_attacker, pc_defender )<2)||(fightskill==ARCHERY))&&!(pc_attacker->npcaitype==4)) // changed from 0x40 to 4 { if (los) { npcsimpleattacktarget(pc_attacker, pc_defender); } } if (pc_attacker->timeout2 > uiCurrentTime) return; //check shotclock memory-BackStab if (fightskill==ARCHERY) Combat->CombatHit(pc_attacker, pc_defender, currenttime,los); else pc_attacker->swingtarg = pc_defender->serial; } SetWeaponTimeout(pc_attacker, pWeapon); pc_attacker->timeout2=pc_attacker->timeout; // set shotclock memory-BackStab if (!pc_defender->isInvul()) { NpcSpellAttack(pc_attacker,pc_defender,currenttime,los); } if (fightskill!=ARCHERY) { Combat->CombatHit(pc_attacker, pc_defender, currenttime, los); // LB !!! //return; // Ripper ???? (Duke) } } } if (pc_defender->hp<1)//Highlight //Repsys { if((pc_attacker->npcaitype==4 || pc_attacker->npcaitype==9) && pc_defender->isNpc()) { npcaction(pc_defender, 0x15); PlayDeathSound(pc_defender); Npcs->DeleteChar(pc_defender);//Guards, don't give body } else { deathstuff(pc_defender); } //murder count \/ if ((pc_attacker->isPlayer())&&(pc_defender->isPlayer()))//Player vs Player { if(pc_defender->isInnocent() && GuildCompare(pc_attacker, pc_defender )==0 ) { ++pc_attacker->kills; UOXSOCKET attacker_socket = calcSocketFromChar(pc_attacker); sysmessage(attacker_socket, tr("You have killed %1 innocent people.").arg(pc_attacker->kills)); //clConsole.send("DEBUG %s's kills are now -> %i\n",pc_attacker->name,pc_attacker->kills); if (pc_attacker->kills==SrvParams->maxkills()+1) sysmessage(attacker_socket, tr("You are now a murderer!")); } if (SrvParams->pvpLog()) { sprintf((char*)temp,"%s was killed by %s!\n",pc_defender->name.c_str(), pc_attacker->name.c_str()); savelog((char*)temp,"PvP.log"); } } npcToggleCombat(pc_attacker); return; // LB } } } }
// CombatHit now expects that LineOfSight has been checked before (Duke, 10.7.2001) void cCombat::CombatHit(P_CHAR pc_attacker, P_CHAR pc_deffender, unsigned int currenttime, short los) { char hit; if (pc_deffender == NULL || pc_attacker == NULL) return; UOXSOCKET s1=calcSocketFromChar(pc_attacker), s2=calcSocketFromChar(pc_deffender); unsigned short fightskill = Skills->GetCombatSkill(pc_attacker), bowtype = Combat->GetBowType(pc_attacker),splitnum,splitcount,hitin; unsigned int basedamage; int damage; // removed from unsigne by Magius(CHE) signed int x; // Magius(CHE) - For armour absorbtion system int maxabs, maxnohabs, tmpj; P_ITEM pWeapon=pc_attacker->getWeapon();// get the weapon item only once if (pWeapon && !(rand()%50) // a 2 percent chance (Duke, 07.11.2000) && pWeapon->type !=9) // but not for spellbooks (Duke, 09/10/00) { pWeapon->hp--; //Take off a hit point if(pWeapon->hp<=0) { sysmessage(s1, tr("Your weapon has been destroyed")); if ((pWeapon->trigon==1) && (pWeapon->layer>0))// -Frazurbluu- Trigger Type 2 is my new trigger type *- { Trig->triggerwitem(s1, pWeapon, 1); // trigger is fired when item destroyed } Items->DeleItem(pWeapon); } } // End here - Magius(CHE) - For armour absorbtion system pc_attacker->swingtarg=-1; if((chardist(pc_attacker, pc_deffender)>1 && fightskill!=ARCHERY) || !los) return; if(pc_deffender->isNpc() && pc_deffender->isInvul()) return; // ripper hit=Skills->CheckSkill(pc_attacker, fightskill, 0, 1000); // increase fighting skill for attacker and defender if (!hit) { if (pc_attacker->isPlayer()) doMissedSoundEffect(pc_attacker); if ((fightskill==ARCHERY)&&(los)) { if (rand()%3-1)//-1 0 or 1 { short id=0x1BFB; // bolts if (bowtype==1) id=0x0F3F; // arrows P_ITEM pAmmo=Items->SpawnItem(pc_deffender,1,"#",1,id,0,0); if(pAmmo) { pAmmo->moveTo(pc_deffender->pos); pAmmo->priv=1; RefreshItem(pAmmo); } } } } else { if (!pc_deffender->isInvul()) { if (pc_deffender->xid==0x0191) soundeffect2(pc_deffender,0x014b); else if (pc_deffender->xid==0x0190) soundeffect2(pc_deffender,0x0156); playmonstersound(pc_deffender, pc_deffender->id(), SND_DEFEND); //AntiChrist -- for poisoned weapons if((pWeapon) && (pWeapon->poisoned>0)) { pc_deffender->poisoned=pWeapon->poisoned; pc_deffender->poisontime=uiCurrentTime+(MY_CLOCKS_PER_SEC*(40/pc_deffender->poisoned)); // a lev.1 poison takes effect after 40 secs, a deadly pois.(lev.4) takes 40/4 secs - AntiChrist pc_deffender->poisonwearofftime=pc_deffender->poisontime+(MY_CLOCKS_PER_SEC*SrvParams->poisonTimer()); //wear off starts after poison takes effect - AntiChrist } CheckPoisoning(s2, pc_attacker, pc_deffender); // attacker poisons defender CheckPoisoning(s1, pc_deffender, pc_attacker); // and vice versa if ((pc_deffender->effDex()>0)) pc_deffender->priv2&=0xFD; // unfreeze if (fightskill!=WRESTLING && los) Combat->ItemSpell(pc_attacker, pc_deffender); if (fightskill!=WRESTLING || pc_attacker->isNpc()) basedamage=Combat->CalcAtt(pc_attacker); // Calc base damage else { if ((pc_attacker->skill[WRESTLING]/100) > 0) { if (pc_attacker->skill[WRESTLING]/100!=0) basedamage=rand()%(pc_attacker->skill[WRESTLING]/100); else basedamage=0; } else basedamage=rand()%2; } if((pc_attacker->isPlayer()) && (fightskill!=WRESTLING)) { if (pWeapon->racehate != 0 && pc_deffender->race != 0)//-Fraz- Racehating combat { if (pWeapon->racehate==pc_deffender->race) { basedamage *=2; if(pc_deffender->isPlayer()) { sysmessage(s2, tr("You scream in agony from being hit by the accursed metal!")); if (pc_deffender->xid == 0x0191) soundeffect2(pc_deffender,0x0152); else if (pc_deffender->xid==0x0190) soundeffect2(pc_deffender,0x0157); }// can add a possible effect below here for npc's being hit } } } Skills->CheckSkill(pc_attacker, TACTICS, 0, 1000); damage=(int)(basedamage*((pc_attacker->skill[TACTICS]+500.0)/1000.0)); // Add Tactical bonus damage=damage+(int)((basedamage*(pc_attacker->st/500.0))); // Add Strength bonus //Adds a BONUS DAMAGE for ANATOMY //Anatomy=100 -> Bonus +20% Damage - AntiChrist (11/10/99) if (Skills->CheckSkill(pc_attacker, ANATOMY, 0, 1000)) { float multiplier=(((pc_attacker->skill[ANATOMY]*20)/1000.0f)/100.0f)+1; damage=(int) (damage * multiplier); } //Adds a BONUS DEFENCE for TACTICS //Tactics=100 -> Bonus -20% Damage - AntiChrist (11/10/99) float multiplier=1-(((pc_deffender->skill[TACTICS]*20)/1000.0f)/100.0f); damage=(int) (damage * multiplier); P_ITEM pShield=pc_deffender->getShield(); if(pShield) { if (Skills->CheckSkill(pc_deffender, PARRYING, 0, 1000))// chance to block with shield { if (pShield->def!=0) damage-=rand()%(pShield->def);// damage absorbed by shield if(rand()%2) pShield->hp--; //Take off a hit point if(pShield->hp<=0) { sysmessage(s2, tr("Your shield has been destroyed")); if ((pShield->trigon==1) && (pShield->layer >0))// -Frazurbluu- Trigger Type 2 is my new trigger type *- { Trig->triggerwitem(s2, pShield, 1); // trigger is fired when item destroyed } Items->DeleItem(pShield); } } } // Armor destruction and sped up by hitting with maces should go in here somewhere // According to lacation of body hit Id imagine -Frazurbluu- **NEEDS ADDED** x=rand()%100;// determine area of body hit if (!SrvParams->combatHitMessage()) { if (x<=44) x=1; // body else if (x<=58) x=2; // arms else if (x<=72) x=3; // head else if (x<=86) x=4; // legs else if (x<=93) x=5; // neck else x=6; // hands } else { temp[0] = '\0'; hitin = rand()%2; if (x<=44) { x=1; // body switch (hitin) { case 1: //later take into account dir facing attacker during battle if (damage < 10) strcpy(temp, "hits you in your Chest!"); else if (damage >=10) strcpy(temp, "lands a terrible blow to your Chest!"); break; case 2: if (damage < 10) strcpy(temp, "lands a blow to your Stomach!"); else if (damage >=10) strcpy(temp, "knocks the wind out of you!"); break; default: if (damage < 10) strcpy(temp, "hits you in your Ribs!"); else if (damage >=10) strcpy(temp, "broken your Rib?!"); } } else if (x<=58) { if (damage > 1) { x=2; // arms switch (hitin) { case 1: strcpy(temp, "hits you in Left Arm!"); break; case 2: strcpy(temp, "hits you in Right Arm!"); break; default:strcpy(temp, "hits you in Right Arm!"); } } } else if (x<=72) { x=3; // head switch (hitin) { case 1: if (damage < 10) strcpy(temp, "hits you you straight in the Face!"); else if (damage >=10) strcpy(temp, "lands a stunning blow to your Head!"); break; case 2: if (damage < 10) strcpy(temp, "hits you to your Head!"); //kolours - (09/19/98) else if (damage >=10) strcpy(temp, "smashed a blow across your Face!"); break; default: if (damage < 10) strcpy(temp, "hits you you square in the Jaw!"); else if (damage >=10) strcpy(temp, "lands a terrible hit to your Temple!"); } } else if (x<=86) { x=4; // legs switch (hitin) { case 1: strcpy(temp, "hits you in Left Thigh!"); break; case 2: strcpy(temp, "hits you in Right Thigh!"); break; default:strcpy(temp, "hits you in Groin!"); } } else if (x<=93) { x=5; // neck strcpy(temp, "hits you to your Throat!"); } else { x=6; // hands switch (hitin) { case 1: if (damage > 1) strcpy(temp, tr("hits you in Left Hand!").latin1()); break; case 2: if (damage > 1) strcpy(temp, tr("hits you in Right Hand!").latin1()); break; default: if (damage > 1) strcpy(temp, tr("hits you in Right Hand!").latin1()); } } sprintf((char*)temp2,"%s %s",pc_attacker->name.c_str(), temp); if (pc_deffender->isPlayer() && s2!=-1) sysmessage(s2, (char*)temp2); //kolours -- hit display } x = CalcDef(pc_deffender,x); // Magius(CHE) - For armour absorbtion system maxabs = 20; // // there are monsters with DEF >20, this makes them undefeatable maxnohabs=100; if (SrvParams->maxAbsorbtion() > 0) { maxabs = SrvParams->maxAbsorbtion(); } if (SrvParams->maxnohabsorbtion() > 0) { maxnohabs = SrvParams->maxnohabsorbtion(); } if (!ishuman(pc_deffender)) maxabs=maxnohabs; tmpj=(int) (damage*x)/maxabs; // Absorbtion by Magius(CHE) damage -= tmpj; if (damage<0) damage=0; if (pc_deffender->isPlayer()) damage /= SrvParams->npcdamage(); // Rate damage against other players // End Armour Absorbtion by Magius(CHE) (See alse reactive armour spell damage) if (pc_attacker->isPlayer())//Zippy ItemCastSpell(s1, pc_deffender,pWeapon); //AntiChrist - 26/10/99 //when hitten and damage >1, defender fails if casting a spell! if(damage>1 && pc_deffender->isPlayer())//only if damage>1 and against a player { if(pc_deffender->casting && currentSpellType[s2]==0 ) {//if casting a normal spell (scroll: no concentration loosen) Magic->SpellFail(s2); currentSpellType[s2]=0; pc_deffender->spell=-1; pc_deffender->casting=0; pc_deffender->spelltime=0; pc_deffender->priv2 &= 0xfd; // unfreeze, bugfix LB } } if(damage>0) { if (pc_deffender->ra) // For reactive armor spell { // -Frazurbluu- RA may need a rewrite to be more OSI standard here // Its said 80% deflected 10% to attacker / 10% defender gotta check special effects int damage1; damage1=(int)( damage*(pc_deffender->skill[MAGERY]/2000.0)); pc_deffender->hp -= damage-damage1; if (pc_deffender->isNpc()) damage1 = damage1 * SrvParams->npcdamage(); // by Magius(CHE) pc_attacker->hp -= damage1; // Remove damage from attacker staticeffect(pc_deffender, 0x37, 0x4A, 0, 15);//RA effect - AntiChrist (9/99) if ((fightskill==MACEFIGHTING) && (IsSpecialMace(pWeapon->id())))// Stamina Loss -Fraz- { //pc_attacker->stm-=3+(rand()%4); } if ((fightskill==FENCING) && (IsFencing2H(pWeapon->id())))// Paralyzing -Fraz- { //will call the combat caused paralyzation **NEED TO DO** } if ((fightskill==SWORDSMANSHIP) && (IsAxe(pWeapon->id())))// Concussion Hit -Fraz- { //will call the combat caused concussion (loss of int for 30 secs) **NEED TO DO** // for now make it subtract mana //pc_attacker->mn-=(pc_attacker->mn/2); } updatestats(pc_attacker, 0); } else { // -Fraz- Now needs adjusted to happen on a skill percentage pc_deffender->hp-=damage; // Remove damage from defender only apply special hits to non-npc's if ((fightskill==MACEFIGHTING) && (IsSpecialMace(pWeapon->id())) && (pc_deffender->isPlayer()))// Stamina Loss -Fraz- { pc_deffender->stm-=3+(rand()%3); } if ((fightskill==FENCING) && (IsFencing2H(pWeapon->id())) && (pc_deffender->isPlayer()))// Paralyzing -Fraz- { tempeffect(pc_attacker, pc_deffender, 44, 0, 0, 0); sysmessage(s1, tr("You delivered a paralyzing blow")); } if ((fightskill==SWORDSMANSHIP) && (IsAxe(pWeapon->id())) && (pc_deffender->isPlayer()))// Concussion Hit -Fraz- { tempeffect(pc_attacker, pc_deffender, 45, 0, 0, 0); //pc_attacker->mn-=(pc_attacker->mn/2); //-Fraz- temp use of this for concussion } updatestats((pc_deffender), 0); } // blood shred by blackwind if (damage>10) { short id = 0x122c; if (damage>50) id=0x122a; else if (damage>40) id=0x122d; else if (damage>30) id=0x122e; else if (damage>20) id=0x122b; P_ITEM pBlood = Items->SpawnItem(pc_deffender, 1, "#", 0, id, 0, 0); if (pBlood) { pBlood->moveTo(pc_deffender->pos); pBlood->priv = 1; pBlood->setGMMovable(); //Moveable by GM RefreshItem(pBlood); pBlood->decaytime = (SrvParams->decayTime()/2)*MY_CLOCKS_PER_SEC+uiCurrentTime; } } ///////// For Splitting NPCs /// McCleod if ((pc_deffender->split>0)&&(pc_deffender->hp>=1)) { if (rand()%100<=pc_deffender->splitchnc) { if (pc_deffender->split==1) splitnum=1; else splitnum=rand()%pc_deffender->split+1; for (splitcount=0;splitcount<splitnum;splitcount++) Npcs->Split(pc_deffender); } } //////// End of spliting NPCs } if (pc_attacker->isPlayer()) if((fightskill==ARCHERY && los)|| fightskill!=ARCHERY) doSoundEffect(pc_attacker, fightskill, pWeapon); if (pc_deffender->hp<0) pc_deffender->hp=0; updatestats((pc_deffender), 0); x = pc_deffender->id(); if (x>=0x0190) { if (!pc_deffender->onhorse) npcaction(pc_deffender, 0x14); } } } }