int16 QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, float y, float z, float heading) { Mob *other = entity_list.GetMobByNpcTypeID(npc_type); if(other != NULL) { return(other->GetID()); } NPCType* tmp = 0; if ((tmp = Database::Instance()->GetNPCType(npc_type))) { NPC* npc = new NPC(tmp, 0, x, y, z, heading); npc->AddLootTable(); entity_list.AddNPC(npc,true); // Quag: Sleep in main thread? ICK! // Sleep(200); // Quag: check is irrelevent, it's impossible for npc to be 0 here // (we're in main thread, nothing else can possibly modify it) // if(npc != 0) { if(grid > 0) { // HarakiriFIXME npc->AssignWaypoints(grid); } npc->SendPosUpdate(); // } return(npc->GetID()); } return(0); }
bool Spawn2::Process() { //Yeahlight: This is where an NPC spawn/respawn happens if (timer->Check()) { timer->Disable(); SpawnGroup* sg = zone->spawn_group_list->GetSpawnGroup(spawngroup_id_); if (sg == 0) return false; SPAWN_TIME_OF_DAY tmp_time_of_day; int32 npcid = sg->GetNPCType(&tmp_time_of_day); if (npcid) { NPCType* tmp = Database::Instance()->GetNPCType(npcid); //Yeahlight: Preventing boats from autospawning for Tazadar if (tmp && tmp->race != 72 && tmp->race != 73) { tmp->time_of_day = tmp_time_of_day; // Kibanu NPC* npc = new NPC(tmp, this, x, y, z, heading, false, roamRange, myRoamBox, myPathGrid, myPathGridStart); npc->AddLootTable(); npc->GetMeleeWeapons(); npc->CalcBonuses(true, true); entity_list.AddNPC(npc); } } else { Reset(); } } return true; }
bool Spawn2::Process() { _ZP(Spawn2_Process); IsDespawned = false; if(!Enabled()) return true; //grab our spawn group SpawnGroup* sg = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); if(NPCPointerValid() && (sg->despawn == 0 || condition_id != 0)) return true; if (timer.Check()) { timer.Disable(); _log(SPAWNS__MAIN, "Spawn2 %d: Timer has triggered", spawn2_id); //first check our spawn condition, if this isnt active //then we reset the timer and try again next time. if(condition_id != SC_AlwaysEnabled && !zone->spawn_conditions.Check(condition_id, condition_min_value)) { _log(SPAWNS__CONDITIONS, "Spawn2 %d: spawning prevented by spawn condition %d", spawn2_id, condition_id); Reset(); return(true); } if (sg == NULL) { database.LoadSpawnGroupsByID(spawngroup_id_,&zone->spawn_group_list); sg = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); } if (sg == NULL) { _log(SPAWNS__MAIN, "Spawn2 %d: Unable to locate spawn group %d. Disabling.", spawn2_id, spawngroup_id_); return false; } //have the spawn group pick an NPC for us uint32 npcid = sg->GetNPCType(); if (npcid == 0) { _log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", spawn2_id, spawngroup_id_); Reset(); //try again later (why?) return(true); } //try to find our NPC type. const NPCType* tmp = database.GetNPCType(npcid); if (tmp == NULL) { _log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", spawn2_id, spawngroup_id_, npcid); Reset(); //try again later return(true); } if(tmp->unique_spawn_by_name) { if(!entity_list.LimitCheckName(tmp->name)) { _log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.", spawn2_id, spawngroup_id_, npcid); timer.Start(5000); //try again in five seconds. return(true); } } if(tmp->spawn_limit > 0) { if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) { _log(SPAWNS__MAIN, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)", spawn2_id, spawngroup_id_, npcid, tmp->spawn_limit); timer.Start(5000); //try again in five seconds. return(true); } } if(sg->despawn != 0 && condition_id == 0) zone->Despawn(spawn2_id); if(IsDespawned) return true; if(spawn2_id) database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0); currentnpcid = npcid; NPC* npc = new NPC(tmp, this, x, y, z, heading, FlyMode3); //DCBOOKMARK npc->mod_prespawn(this); npcthis = npc; npc->AddLootTable(); npc->SetSp2(spawngroup_id_); npc->SaveGuardPointAnim(anim); npc->SetAppearance((EmuAppearance)anim); entity_list.AddNPC(npc); //this limit add must be done after the AddNPC since we need the entity ID. entity_list.LimitAddNPC(npc); if(sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay) npc->AI_SetRoambox(sg->roamdist,sg->roambox[0],sg->roambox[1],sg->roambox[2],sg->roambox[3],sg->delay); if(zone->InstantGrids()) { _log(SPAWNS__MAIN, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f).", spawn2_id, spawngroup_id_, npc->GetName(), npcid, x, y, z); LoadGrid(); } else { _log(SPAWNS__MAIN, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f). Grid loading delayed.", spawn2_id, spawngroup_id_, tmp->name, npcid, x, y, z); } } return true; }
bool Spawn2::Process() { IsDespawned = false; if (!Enabled()) return true; //grab our spawn group SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); if (NPCPointerValid() && (spawn_group->despawn == 0 || condition_id != 0)) { return true; } if (timer.Check()) { timer.Disable(); Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Timer has triggered", spawn2_id); //first check our spawn condition, if this isnt active //then we reset the timer and try again next time. if (condition_id != SC_AlwaysEnabled && !zone->spawn_conditions.Check(condition_id, condition_min_value)) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: spawning prevented by spawn condition %d", spawn2_id, condition_id); Reset(); return (true); } if (spawn_group == nullptr) { database.LoadSpawnGroupsByID(spawngroup_id_, &zone->spawn_group_list); spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); } if (spawn_group == nullptr) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Unable to locate spawn group %d. Disabling.", spawn2_id, spawngroup_id_); return false; } //have the spawn group pick an NPC for us uint32 npcid = spawn_group->GetNPCType(); if (npcid == 0) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d did not yeild an NPC! not spawning.", spawn2_id, spawngroup_id_); Reset(); //try again later (why?) return (true); } //try to find our NPC type. const NPCType *tmp = database.LoadNPCTypesData(npcid); if (tmp == nullptr) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded an invalid NPC type %d", spawn2_id, spawngroup_id_, npcid); Reset(); //try again later return (true); } if (tmp->unique_spawn_by_name) { if (!entity_list.LimitCheckName(tmp->name)) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is unique and one already exists.", spawn2_id, spawngroup_id_, npcid); timer.Start(5000); //try again in five seconds. return (true); } } if (tmp->spawn_limit > 0) { if (!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn group %d yeilded NPC type %d, which is over its spawn limit (%d)", spawn2_id, spawngroup_id_, npcid, tmp->spawn_limit); timer.Start(5000); //try again in five seconds. return (true); } } bool ignore_despawn = false; if (npcthis) { ignore_despawn = npcthis->IgnoreDespawn(); } if (ignore_despawn) { return true; } if (spawn_group->despawn != 0 && condition_id == 0 && !ignore_despawn) { zone->Despawn(spawn2_id); } if (IsDespawned) { return true; } currentnpcid = npcid; NPC *npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), GravityBehavior::Water); npc->mod_prespawn(this); npcthis = npc; npc->AddLootTable(); if (npc->DropsGlobalLoot()) { npc->CheckGlobalLootTables(); } npc->SetSp2(spawngroup_id_); npc->SaveGuardPointAnim(anim); npc->SetAppearance((EmuAppearance) anim); entity_list.AddNPC(npc); //this limit add must be done after the AddNPC since we need the entity ID. entity_list.LimitAddNPC(npc); /** * Roambox init */ if (spawn_group->roamdist && spawn_group->roambox[0] && spawn_group->roambox[1] && spawn_group->roambox[2] && spawn_group->roambox[3] && spawn_group->delay && spawn_group->min_delay) { npc->AI_SetRoambox( spawn_group->roamdist, spawn_group->roambox[0], spawn_group->roambox[1], spawn_group->roambox[2], spawn_group->roambox[3], spawn_group->delay, spawn_group->min_delay ); } if (zone->InstantGrids()) { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f).", spawn2_id, spawngroup_id_, npc->GetName(), npcid, x, y, z); LoadGrid(); } else { Log(Logs::Detail, Logs::Spawns, "Spawn2 %d: Group %d spawned %s (%d) at (%.3f, %.3f, %.3f). Grid loading delayed.", spawn2_id, spawngroup_id_, tmp->name, npcid, x, y, z); } } return true; }
void Client::GoFish() { //TODO: generate a message if we're already fishing /*if (!fishing_timer.Check()) { //this isn't the right check, may need to add something to the Client class like 'bool is_fishing' Message_StringID(0, ALREADY_FISHING); //You are already fishing! return; }*/ fishing_timer.Disable(); //we're doing this a second time (1st in Client::Handle_OP_Fishing) to make sure that, between when we started fishing & now, we're still able to fish (in case we move, change equip, etc) if (!CanFish()) //if we can't fish here, we don't need to bother with the rest return; //multiple entries yeilds higher probability of dropping... uint32 common_fish_ids[MAX_COMMON_FISH_IDS] = { 1038, // Tattered Cloth Sandals 1038, // Tattered Cloth Sandals 1038, // Tattered Cloth Sandals 13019, // Fresh Fish 13076, // Fish Scales 13076, // Fish Scales 7007, // Rusty Dagger 7007, // Rusty Dagger 7007 // Rusty Dagger }; //success formula is not researched at all int fishing_skill = GetSkill(FISHING); //will take into account skill bonuses on pole & bait //make sure we still have a fishing pole on: int32 bslot = m_inv.HasItemByUse(ItemTypeFishingBait, 1, invWhereWorn|invWherePersonal); const ItemInst* Bait = NULL; if(bslot != SLOT_INVALID) Bait = m_inv.GetItem(bslot); //if the bait isnt equipped, need to add its skill bonus if(bslot >= IDX_INV && Bait->GetItem()->SkillModType == FISHING) { fishing_skill += Bait->GetItem()->SkillModValue; } if (fishing_skill > 100) { fishing_skill = 100+((fishing_skill-100)/2); } if (MakeRandomInt(0,175) < fishing_skill) { uint32 food_id = 0; //25% chance to fish an item. if (MakeRandomInt(0, 399) <= fishing_skill ) { uint32 npc_id = 0; uint8 npc_chance = 0; food_id = database.GetZoneFishing(m_pp.zone_id, fishing_skill, npc_id, npc_chance); //check for add NPC if(npc_chance > 0 && npc_id) { if(npc_chance < MakeRandomInt(0, 99)) { const NPCType* tmp = database.GetNPCType(npc_id); if(tmp != NULL) { NPC* npc = new NPC(tmp, NULL, GetX()+3, GetY(), GetZ(), GetHeading(), FlyMode3); npc->AddLootTable(); npc->AddToHateList(this, 1, 0, false); //no help yelling entity_list.AddNPC(npc); Message(MT_Emote, "You fish up a little more than you bargained for..."); } } } } //consume bait, should we always consume bait on success? DeleteItemInInventory(bslot, 1, true); //do we need client update? if(food_id == 0) { int index = MakeRandomInt(0, MAX_COMMON_FISH_IDS-1); food_id = common_fish_ids[index]; } const Item_Struct* food_item = database.GetItem(food_id); Message_StringID(MT_Skills, FISHING_SUCCESS); const ItemInst* inst = database.CreateItem(food_item, 1); if(inst != NULL) { if(CheckLoreConflict(inst->GetItem())) { this->Message_StringID(0,DUP_LORE); } else { PushItemOnCursor(*inst); // changed from PutItemInInventory(SLOT_CURSOR, *inst); - was additional overhead SendItemPacket(SLOT_CURSOR,inst,ItemPacketSummonItem); if(RuleB(TaskSystem, EnableTaskSystem)) UpdateTasksForItem(ActivityFish, food_id); } safe_delete(inst); } parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != NULL ? inst->GetItem()->ID : 0); } else { //chance to use bait when you dont catch anything... if (MakeRandomInt(0, 4) == 1) { DeleteItemInInventory(bslot, 1, true); //do we need client update? Message_StringID(MT_Skills, FISHING_LOST_BAIT); //You lost your bait! } else { if (MakeRandomInt(0, 15) == 1) //give about a 1 in 15 chance to spill your beer. we could make this a rule, but it doesn't really seem worth it //TODO: check for & consume an alcoholic beverage from inventory when this triggers, and set it as a rule that's disabled by default Message_StringID(MT_Skills, FISHING_SPILL_BEER); //You spill your beer while bringing in your line. else Message_StringID(MT_Skills, FISHING_FAILED); //You didn't catch anything. } parse->EventPlayer(EVENT_FISH_FAILURE, this, "", 0); } //chance to break fishing pole... //this is potentially exploitable in that they can fish //and then swap out items in primary slot... too lazy to fix right now if (MakeRandomInt(0, 49) == 1) { Message_StringID(MT_Skills, FISHING_POLE_BROKE); //Your fishing pole broke! DeleteItemInInventory(13,0,true); } if(CheckIncreaseSkill(FISHING, NULL, 5)) { if(title_manager.IsNewTradeSkillTitleAvailable(FISHING, GetRawSkill(FISHING))) NotifyNewTitlesAvailable(); } }
void Client::CheckQuests(const char* zonename, const char * message, int32 npc_id, uint16 item_id, Mob* other) { bool ps = false; bool tt = false; bool ti = false; bool tt2 = false; bool ti2 = false; bool stt = false; bool std = false; bool td = false; bool sta = false; bool ta = false; bool sti = false; bool stf = false; bool tf = false; bool tk = false; bool stk = false; bool levelcheck = false; int8 fac = GetFactionLevel(GetID(),other->GetNPCTypeID(), GetRace(), GetClass(), DEITY_AGNOSTIC, other->CastToNPC()->GetPrimaryFaction(), other); FILE * pFile; long lSize; char * buffer; char filename[255]; #ifdef WIN32 snprintf(filename, 254, "quests\\%i.qst", npc_id); #else snprintf(filename, 254, "quests/%i.qst", npc_id); #endif adverrorinfo = 940; if ((pFile=fopen(filename,"rb"))) { #ifdef DEBUG printf("Reading quests from %s\n", filename); #endif } else { #ifdef DEBUG printf("Error: No quests file found for %s\n", filename); #endif return; } if (pFile==NULL) exit (1); // obtain file size. fseek (pFile , 0 , SEEK_END); lSize = ftell (pFile); rewind (pFile); adverrorinfo = 941; // allocate memory to contain the whole file. buffer = (char*) malloc (lSize); if (buffer == NULL) exit (2); // copy the file into the buffer. fread (buffer,1,lSize,pFile); fclose(pFile); Seperator3 sep3(buffer); for(int i=0; i < 2048; ++i) { // printf("Temp: %s\n", sep3.arghz[i]); char * command; char * temp; temp = sep3.arghz[i]; if (temp == NULL) return; Seperator sep(temp); Seperator4 sep4(temp); command = sep4.arghza[0]; command = strupr(command); #ifdef DEBUG cout<<sep.argplus[0]<<endl; #endif if (!IsCommented(temp)) { if (strstr(command,"END_FILE") != NULL || command == NULL) { break; } if (ti2 || tt2 || tf || td || ta) { char lvl[5]; sprintf(lvl, "%i", this->GetLevel()); strcpy(sep4.arghza[1], strreplace(sep4.arghza[1],"%CHARRACE%", GetRaceName(this->GetRace()))); strcpy(sep4.arghza[1], strreplace(sep4.arghza[1],"%CHARLEVEL%", lvl)); strcpy(sep4.arghza[1], strreplace(sep4.arghza[1],"%CHARCLASS%", GetEQClassName(this->GetClass(), 50))); char * nmessage = strreplace(sep4.arghza[1],"%CHARNAME%", this->GetName()); nmessage[strlen(nmessage) - 1] = '\0'; if (ti2 || tt2 || ta) { other->CastToNPC()->FaceTarget(this, true); } if ((fac == 7 || fac == 6) && (ti2 || tt2)) { entity_list.NPCMessage(other,true,200,0,"%s says, 'I will have nothing to do with such as you. Begone.'",other->GetName()); break; } else if (strstr(command,"FACTION_CHECK") != NULL) { int8 fac2 = atoi(sep.arg[1]); if ((fac2 <= 5 && fac > fac2) || (fac2 == 6 && fac == 8)) { entity_list.NPCMessage(other,true,200,0,"%s says, 'I will have nothing to do with such as you. Begone.'",other->GetName()); break; } ps = true; } else if (strstr(command,"SAY") != NULL) { entity_list.NPCMessage(this, false, 400, 0, "%s says, '%s'", other->GetName(), nmessage); ps = true; } else if (strstr(command,"EMOTE") != NULL) { cout<<"Emoting!"<<endl; entity_list.NPCMessage(this, false, 400, 0, "%s %s", other->GetName(), nmessage); ps = true; } else if (strstr(command,"TEXT") != NULL) { entity_list.NPCMessage(this, false, 400, 0, "%s", nmessage); ps = true; } else if (strstr(command,"SHOUT") != NULL) { entity_list.NPCMessage(this, false, 0, 13, "%s shouts, '%s'", other->GetName(), nmessage); ps = true; } else if (strstr(command,"SPAWN_ITEM") != NULL) { this->SummonItem(atoi(sep.arg[1])); ps = true; } else if (strstr(command,"ADD_HATELIST") != NULL) { other->CastToNPC()->AddToHateList(this, 100); ps = true; } else if (strstr(command,"DEPOP") != NULL) { other->CastToNPC()->Depop(); ps = true; } #ifdef GUILDWARS else if (strstr(command,"CITYTAKE") != NULL) { if(IsClient() && GuildDBID() != 0) { if(target->CastToNPC()->GetGuildOwner() == GuildDBID()) { entity_list.NPCMessage(this, false, 400, 0, "%s says, 'You are a member of the guild that owns this city, why would you want to conquere it?'", other->GetName(), nmessage); } else if(!IsAttackAllowed(other)) { entity_list.NPCMessage(this, false, 400, 0, "%s says, 'You cannot conquere an allied city.'", other->GetName(), nmessage); } else if(database.CityDefense(zone->GetZoneID(),0)) { entity_list.NPCMessage(this, false, 400, 0, "%s says, 'This city still has men standing, I will not surrender!'", other->GetName(), nmessage); } else if(database.SetCityGuildOwned(GuildDBID(),other->GetNPCTypeID())) { entity_list.NPCMessage(this, false, 400, 0, "%s says, 'You have won, I surrender to you.'", other->GetName(), nmessage); zone->SetGuildOwned(GuildDBID()); zone->Repop(); } } ps = true; } #endif else if (strstr(command,"SPAWN_NPC") != NULL) { adverrorinfo = 751; const NPCType* tmp = 0; adverrorinfo = 752; int16 grid = atoi(sep.arg[2]); int8 guildwarset = atoi(sep.arg[3]); if ((tmp = database.GetNPCType(atoi(sep.arg[1])))) { adverrorinfo = 753; NPC* npc = new NPC(tmp, 0, other->GetX(), other->GetY(), other->GetZ(), heading); adverrorinfo = 754; npc->AddLootTable(); adverrorinfo = 755; entity_list.AddNPC(npc,true,true); adverrorinfo = 756; Sleep(200); if(npc != 0) { if(grid > 0) npc->AssignWaypoints(grid); adverrorinfo = 757; #ifdef GUILDWARS if(guildwarset > 0 && guildwarset == 1 && GuildDBID() > 0) npc->SetGuildOwner(GuildDBID()); #endif adverrorinfo = 758; npc->SendPosUpdate(); } } ps = true; } else if (strstr(command,"LEVEL_CHECK") != NULL) { int8 Level1 = atoi(sep.arg[1]); int8 Level2 = atoi(sep.arg[2]); int8 Levelp = this->GetLevel(); if(Level2 == 0 || Level2 == NULL){ //Min Level if(Level1 > Levelp) { //not high enough to talk too break; } } else{ //Level Range if(Level1 < Levelp && Level2 < Levelp) { //not in the req level range break; } } levelcheck = true; } else if (strstr(command,"CUMULATIVE_FLAG") != NULL) { other->flag[50] = other->flag[50] + 1; ps = true; } else if (strstr(command,"NPC_FLAG") != NULL) { other->flag[atoi(sep.arg[1])] = atoi(sep.arg[2]); ps = true; } else if (strstr(command,"PLAYER_FLAG") != NULL) { this->flag[atoi(sep.arg[1])] = atoi(sep.arg[2]); ps = true; } else if (strstr(command,"EXP") != NULL) { this->AddEXP (atoi(sep.arg[1])); ps = true; } else if (strstr(command,"LEVEL") != NULL) { this->SetLevel(atoi(sep.arg[1]), true); ps = true; } else if (strstr(command,"SAFEMOVE") != NULL) { this->MovePC(zone->GetShortName(),database.GetSafePoint(zone->GetShortName(),"x"),database.GetSafePoint(zone->GetShortName(),"y"),database.GetSafePoint(zone->GetShortName(),"z"),false,false); ps = true; } else if (strstr(command,"RAIN") != NULL) { zone->zone_weather = atoi(sep.arg[1]); APPLAYER* outapp = new APPLAYER; outapp = new APPLAYER; outapp->opcode = OP_Weather; outapp->pBuffer = new uchar[8]; memset(outapp->pBuffer, 0, 8); outapp->size = 8; outapp->pBuffer[4] = atoi(sep.arg[1]); // Why not just use 0x01/2/3? entity_list.QueueClients(this, outapp); delete outapp; ps = true; } else if (strstr(command,"SNOW") != NULL) { zone->zone_weather = atoi(sep.arg[1]) + 1; APPLAYER* outapp = new APPLAYER; outapp = new APPLAYER; outapp->opcode = OP_Weather; outapp->pBuffer = new uchar[8]; memset(outapp->pBuffer, 0, 8); outapp->size = 8; outapp->pBuffer[0] = 0x01; outapp->pBuffer[4] = atoi(sep.arg[1]); entity_list.QueueClients(this, outapp); delete outapp; ps = true; } else if (strstr(command,"GIVE_CASH") != NULL) { this->AddMoneyToPP(atoi(sep.arg[1]),true); ps = true; } else if (strstr(command,"GIVE_ITEM") != NULL) { int16 ItemID = atoi(sep.arg[1]); sint8 ItemCharges = atoi(sep.arg[2]); this->SummonItem(ItemID, ItemCharges); ps = true; } else if (strstr(command,"CAST_SPELL") != NULL) { other->CastSpell(atoi(sep.arg[1]),this->GetID()); ps = true; } else if (strstr(command,"PVP") != NULL) { if (strstr(strupr(sep.arg[1]),"ON") != NULL) this->CastToClient()->SetPVP(true); else this->CastToClient()->SetPVP(false); ps = true; } /*else if (strstr(command,"CHANGEFACTION") != NULL) { if ((sep.IsNumber(1)) && (sep.IsNumber(2))) { this->CastToClient()->SetFactionLevel2(this->CastToClient()->CharacterID(),atoi(sep.arg[1]), this->CastToClient()->GetClass(), this->CastToClient()->GetRace(), this->CastToClient()->GetDeity(), atoi(sep.arg[2])); this->CastToClient()->Message(0,BuildFactionMessage(GetCharacterFactionLevel(atoi(sep.arg[1])),atoi(sep.arg[1]))); } else { cout << "Error in script!!!!! Bad CHANGEFACTION Line! " << endl; } ps = true; }*/ else if (strstr(command,"DO_ANIMATION") != NULL) { other->DoAnim(atoi(sep.arg[1])); ps = true; } else if (strstr(command,"ADDSKILL") != NULL) { if (sep.IsNumber(1) && sep.IsNumber(2) && (atoi(sep.arg[2]) >= 0 || atoi(sep.arg[2]) <= 252) && (atoi(sep.arg[1]) >= 0 && atoi(sep.arg[1]) < 74)) { this->AddSkill(atoi(sep.arg[1]), atoi(sep.arg[2])); } else cout << "Error in script!!!! Bad ADDSKILL line!" << endl; ps = true; } else if (strstr(command,"FLAG_CHECK") != NULL) { if (this->flag[atoi(sep.arg[1])] == 0) break; else this->flag[atoi(sep.arg[1])] = 0; ps = true; } else if (strstr(command,"CHANCE") != NULL) { if (rand()%100 > atoi(sep.arg[1])) break; ps = true; } } if (IsEnd(temp)) { tt = false; tt2 = false; stt = false; ti = false; ti2 = false; sti = false; tk = false; td = false; std = false; ta = false; sta = false; tf = false; stf = false; stk = false; } if (strstr(command,"TRIGGER_ATTACK") != NULL) { if (strstr(message,"%%ATTACK%%") != NULL) { adverrorinfo = 943; ta = true; } else { sta = true; } } else if (strstr(command,"TRIGGER_DEATH") != NULL) { if (strstr(message,"%%DEATH%%") != NULL) { td = true; } else { std = true; } } else if (strstr(command,"TRIGGER_KILLED") != NULL) { if (strstr(message,"%%KILLED%%") != NULL) { tk = true; } else { stk = true; } } else if (strstr(command,"TRIGGER_FLAGS") != NULL) { int8 flag1 = atoi(sep.arg[1]); int8 flag2 = atoi(sep.arg[2]); int8 flag3 = atoi(sep.arg[3]); int8 flag4 = atoi(sep.arg[4]); if (flag1 == 50) { if (other->flag[50] >= atoi(sep.arg[2])) { tf = true; other->flag[50] = 0; } else stf = true; } else { if (ta || tt || ti) stf = true; else if (flag1 > 0 && other->flag[flag1] == 0) stf = true; else if (flag2 > 0 && other->flag[flag2] == 0) stf = true; else if (flag3 > 0 && other->flag[flag3] == 0) stf = true; else if (flag4 > 0 && other->flag[flag4] == 0) stf = true; else { tf = true; if (flag1 > 0) other->flag[flag1] = 0; if (flag2 > 0) other->flag[flag2] = 0; if (flag3 > 0) other->flag[flag3] = 0; if (flag4 > 0) other->flag[flag4] = 0; } } } else if (strstr(command,"TRIGGER_ITEM") != NULL) { if (!ta && !tt && !ti) { if ((uint16)item_id == atoi(sep4.arghza[1])) { ti = true; ti2 = true; } else { sti = true; } } else { printf("TRIGGER_ITEM Error at line %d: missing left curly bracket\n", i); return; } } else if (strstr(command,"TRIGGER_TEXT") != NULL) { if (strstr(message,"%%DEATH%%") == NULL && strstr(message,"%%ITEM%%") == NULL && strstr(message,"%%ATTACK%%") == NULL && strstr(message,"%%KILLED%%") == NULL && Dist(other) <= 50) { char* tmp = new char[strlen(message)+1]; strcpy(tmp, message); strupr(tmp); if (strstr(tmp,strupr(sep4.arghza[1])) != NULL) { tt2 = true; tt = true; } else { stt = true; } delete tmp; } else if (strstr(message,"%%DEATH%%") != NULL || strstr(message,"%%item%%") != NULL || strstr(message,"%%attack%%")) { stt = true; } else if (!ps) { printf("TRIGGER_TEXT Error at line %d: Not in NPC_Script\n", i); return; } else { printf("TRIGGER_TEXT Error at line %d: missing left curly bracket\n", i); return; } } /*#ifdef WIN32 delete command; delete temp; #endif*/ } } if (!ps && item_id != 0) { entity_list.NPCMessage(this,true,200,0,"%s has no use for this item.",other->GetName()); SummonItem(item_id); } delete buffer; }