ProximityList::~ProximityList() { #ifdef PSPROXDEBUG CPrintf(CON_DEBUG, "Destruction of cel Proximity List (%p)!\n", this ); #endif while (objectsThatIWatch.GetSize()) { #ifdef PSPROXDEBUG CPrintf(CON_DEBUG, "Unsubscribing from %s (%p).\n", objectsThatIWatch[0]->GetName(), this); #endif objectsThatIWatch[0]->GetProxList()->RemoveWatcher(self); objectsThatIWatch.DeleteIndex(0); objectsThatIWatch_touched.DeleteIndex(0); } while ( objectsThatWatchMe.GetSize() ) { gemObject *obj = (gemObject *)objectsThatWatchMe.Get(0).object; #ifdef PSPROXDEBUG CPrintf(CON_DEBUG, "Unsubscribing from %s (%p).\n",obj->GetName(), this ); #endif obj->GetProxList()->EndWatching(self); } self = NULL; }
void psNPCLoader::ReadSkills() { csRef<iDocumentNode> xmlnode = npcRoot->GetNode("skills"); if(!xmlnode) { CPrintf(CON_WARNING, "Warning: no <skills> tag found\n"); return; } csRef<iDocumentNodeIterator> iter = xmlnode->GetNodes("skill"); while(iter->HasNext()) { csString skill; int value; csRef<iDocumentNode> skillnode = iter->Next(); skill = skillnode->GetAttributeValue("name"); value = skillnode->GetAttributeValueAsInt("value"); psSkillInfo* skillInfo = psserver->GetCacheManager()->GetSkillByName(skill); if(skillInfo!=NULL) { npc->Skills().SetSkillRank(skillInfo->id, value); } else { CPrintf(CON_WARNING, "Unknown skill '%s'... skipping\n",skill.GetData()); } } }
void Tribe::SaveResource(Resource* resource, bool newResource) { const char* fields[] = {"tribe_id","name","amount"}; psStringArray values; values.FormatPush("%d",GetID()); values.FormatPush("%s",resource->name.GetDataSafe()); values.FormatPush("%d",resource->amount); if(newResource) { resource->id = db->GenericInsertWithID("sc_tribe_resources",fields,values); if(id == 0) { CPrintf(CON_ERROR, "Failed to save resource for tribe: %s.\n", db->GetLastError()); return; } } else { csString id; id.Format("%d",resource->id); if(!db->GenericUpdateWithID("sc_tribe_resources","id",id,fields,values)) { CPrintf(CON_ERROR, "Failed to save resource for tribe: %s.\n", db->GetLastError()); return; } } }
void psNPCLoader::ReadKnowledgeAreas() { knowledgeAreas.Empty(); csRef<iDocumentNode> xmlnode = npcRoot->GetNode("knowledgeareas"); if(!xmlnode) { CPrintf(CON_ERROR, "Error: no <knowledgeareas> tag found\n"); return; } csRef<iDocumentNodeIterator> iter = xmlnode->GetNodes("knowledgearea"); while(iter->HasNext()) { csRef<iDocumentNode> areanode = iter->Next(); csString area; int priority; area = areanode->GetAttributeValue("name"); priority = areanode->GetAttributeValueAsInt("priority"); if(area.IsEmpty() || priority==0) { CPrintf(CON_ERROR, "Error: invalid name or priority in <knowledgearea> \n"); return; } knowledgeAreas.Push(area); knowledgeAreasPriority.Push(priority); } }
void ServerConsole::ExecuteScript(const char* script) { const char* bufptr = script; while ( *bufptr != 0) { // skip empty lines while (*bufptr == '\n') bufptr++; char line[1000]; size_t len = strcspn(bufptr, "\n"); memcpy (line, bufptr, len); line[len] = '\0'; bufptr += len; char* strippedline = stripwhite(line); if ((strippedline[0] == '#') || (strippedline[0] == '\0')) continue; char actualcommand[1000]; strcpy(actualcommand, strippedline); size_t commentbegin = strcspn(actualcommand, "#"); actualcommand[commentbegin] = '\0'; if (actualcommand[0] == '\0') continue; CPrintf (CON_CMDOUTPUT, COL_BLUE "%s: " COL_NORMAL, prompt); CPrintf (CON_CMDOUTPUT, "%s\n", actualcommand); execute_line(actualcommand,NULL); } }
void psNPCLoader::ReadMerchantInfo() { buys.Empty(); sells.Empty(); csRef<iDocumentNode> xmlnode = npcRoot->GetNode("buys"); if(!xmlnode) CPrintf(CON_WARNING, "Warning: no <buys> tag found\n"); else { csRef<iDocumentNodeIterator> iter = xmlnode->GetNodes("buy"); while(iter->HasNext()) { csString name; csRef<iDocumentNode> buynode = iter->Next(); name = buynode->GetAttributeValue("name"); psItemCategory* itemCategory = psserver->GetCacheManager()->GetItemCategoryByName(name); if(itemCategory!=NULL) { buys.Push(itemCategory->id); } else { CPrintf(CON_WARNING, "Unknown Item Category (Buy): '%s'... skipping\n",name.GetData()); } } } xmlnode = npcRoot->GetNode("sells"); if(!xmlnode) CPrintf(CON_WARNING, "Warning: no <sells> tag found\n"); else { csRef<iDocumentNodeIterator> iter = xmlnode->GetNodes("sell"); while(iter->HasNext()) { // read data from <sells> section csString name; csRef<iDocumentNode> sellnode = iter->Next(); name = sellnode->GetAttributeValue("name"); psItemCategory* itemCategory = psserver->GetCacheManager()->GetItemCategoryByName(name); if(itemCategory!=NULL) { sells.Push(itemCategory->id); } else { CPrintf(CON_WARNING, "Unknown Item Category (Sell): '%s'... skipping\n",name.GetData()); } } } }
bool psNPCLoader::ReadBasicInfo() { csString name, race, sex, invulnerable; float kill_exp; name = npcRoot->GetAttributeValue("name"); race = npcRoot->GetAttributeValue("race"); sex = npcRoot->GetAttributeValue("sex"); invulnerable = npcRoot->GetAttributeValue("invulnerable"); kill_exp = npcRoot->GetAttributeValueAsFloat("kill_exp"); if(name.IsEmpty()) { CPrintf(CON_ERROR, "Error: No name specified\n"); return false; } if(race.IsEmpty()) { CPrintf(CON_ERROR, "Error: No race specified\n"); return false; } if(sex.IsEmpty()) { CPrintf(CON_ERROR, "Error: No gender specified\n"); return false; } PSCHARACTER_GENDER gender; if(sex=='f'||sex=='F') gender = PSCHARACTER_GENDER_FEMALE; else if(sex=='m' || sex=='M') gender = PSCHARACTER_GENDER_MALE; else if(sex=='n' || sex=='N') gender = PSCHARACTER_GENDER_NONE; else { CPrintf(CON_ERROR, "Error: Unknown gender: %s\n", sex.GetData()); return false; } psRaceInfo* raceInfo = psserver->GetCacheManager()->GetRaceInfoByNameGender(race, gender); if(!raceInfo) { CPrintf(CON_ERROR, "Error: Unknown race: %s gender: %s\n",race.GetData(), sex.GetData()); return false; } npc->SetName(name); npc->SetRaceInfo(raceInfo); npc->SetImperviousToAttack((invulnerable=="Y") ? ALWAYS_IMPERVIOUS : 0); npc->SetKillExperience((int) kill_exp); return true; }
void CharCreationManager::HandleCharDelete(MsgEntry* me, Client* client) { psCharDeleteMessage msg(me); csString charName = msg.charName; if(!charName.Length()) { CPrintf(CON_WARNING,"Client %u sent malformed character name to deletion code!",client->GetClientNum()); return; // No char } PID pid = psserver->CharacterLoader.FindCharacterID(client->GetAccountID(), charName); csString error; if(psserver->CharacterLoader.AccountOwner(charName, client->GetAccountID())) { // Found the char? if(!pid.IsValid()) { psserver->SendSystemError(client->GetClientNum(),"Couldn't find character data!"); return; } // Can we delete it? if(!psserver->CharacterLoader.DeleteCharacterData(pid, error)) { psserver->SendSystemError(client->GetClientNum(),"Error: %s",error.GetData()); return; } // Remove cached objects to make sure that the client gets a fresh character // list from the database. iCachedObject* obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("list",client->GetAccountID().Unbox())); if(obj) { obj->ProcessCacheTimeout(); obj->DeleteSelf(); } obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("auth", client->GetAccountID().Unbox())); if(obj) { obj->ProcessCacheTimeout(); obj->DeleteSelf(); } // Ok, we deleted it psCharDeleteMessage response(charName, me->clientnum); response.SendMessage(); } else { CPrintf(CON_WARNING,"Character %s not deleted because of non-ownership\n", charName.GetData()); psserver->SendSystemError(client->GetClientNum(),"You do not own that character!"); return; } }
//----------------------------------------------------------------------------- bool psNPCLoader::SaveToFile(int id, csString &filename) { filename.Insert(0,"/this/"); psCharacterLoader loader; npc = loader.LoadCharacterData(id,false); if(!npc) { CPrintf(CON_ERROR, "Error: Couldn't load NPC with id: %i\n",id); return false; } //*npc = *character; // removed npcID = id; area = npc->GetCharName(); csRef<iDocumentSystem> xml; xml.AttachNew(new csTinyDocumentSystem); csRef<iDocument> doc = xml->CreateDocument(); csRef<iDocumentNode> root = doc->CreateRoot(); npcRoot = root->CreateNodeBefore(CS_NODE_ELEMENT); npcRoot->SetValue("npc"); WriteBasicInfo(); WriteDescription(); WriteLocation(); WriteStats(); WriteMoney(); WriteEquipment(); WriteFactions(); WriteSkills(); WriteMerchantInfo(); WriteTrainerInfo(); WriteKnowledgeAreas(); WriteSpecificKnowledge(); csRef<iVFS> vfs = csQueryRegistry<iVFS> (psserver->GetObjectReg()); if(!vfs) return false; csString error = doc->Write(vfs, filename); if(!error.IsEmpty()) { CPrintf(CON_ERROR, "Error writing to file %s: %s\n",filename.GetData(), error.GetData()); return false; } return true; }
void Tribe::DumpRecipesToConsole() { CPrintf(CON_CMDOUTPUT, "Dumping recipe list for tribe %d\n", GetID()); CPrintf(CON_CMDOUTPUT, "+------------------------------------------------------------+\n"); CPrintf(CON_CMDOUTPUT, "| No | ID | Name |Pers|Prio|Wait|Step|\n"); CPrintf(CON_CMDOUTPUT, "+------------------------------------------------------------+\n"); tribalRecipe->DumpRecipeTree(); CPrintf(CON_CMDOUTPUT, "+------------------------------------------------------------+\n"); tribalRecipe->DumpRecipeTreeRecipes(); }
void Tribe::SaveAsset(Tribe::Asset* asset, bool deletion) { if(deletion) { if(db->Command("DELETE FROM sc_tribe_assets WHERE id=%u",asset->id)) { asset->id = -1; } } else { const char* fields[] = {"tribe_id", "name", "type","coordX", "coordY", "coordZ", "sector_id", "itemID", "quantity", "status"}; psStringArray values; values.FormatPush("%d",GetID()); values.FormatPush("%s",asset->name.GetData()); values.FormatPush("%d",asset->type); values.FormatPush("%f",asset->pos[0]); values.FormatPush("%f",asset->pos[1]); values.FormatPush("%f",asset->pos[2]); values.FormatPush("%d",asset->sector?Location::GetSectorID(db,asset->sector->QueryObject()->GetName()):-1); values.FormatPush("%d",asset->itemUID); values.FormatPush("%d",asset->quantity); values.FormatPush("%d",asset->status); if(asset->id == -1) { // It's a new entry asset->id = db->GenericInsertWithID("sc_tribe_assets",fields,values); if(id == 0) { CPrintf(CON_ERROR, "Failed to save asset for tribe: %s.\n", db->GetLastError()); return; } } else { // Old entry updated csString id; id.Format("%d",asset->id); if(!db->GenericUpdateWithID("sc_tribe_assets","id",id,fields,values)) { CPrintf(CON_ERROR, "Failed to save asset for tribe: %s.\n", db->GetLastError()); return; } } } }
void Tribe::DumpKnowledge() { CPrintf(CON_CMDOUTPUT, "Dumping knowledge for tribe %d\n", GetID()); if(knowledge.GetSize() == 0) { CPrintf(CON_CMDOUTPUT, "No knowledge.\n"); } for(size_t i=0; i<knowledge.GetSize(); i++) { CPrintf(CON_CMDOUTPUT, "%s ", knowledge[i].GetData()); } CPrintf(CON_CMDOUTPUT, "\n"); }
void NPCType::DumpReactionList(NPC *npc) { CPrintf(CON_CMDOUTPUT, "%-25s %-25s %-5s %-10s %-20s %s\n","Reaction","Type","Range","Value","Last","Affects"); for (size_t i=0; i<reactions.GetSize(); i++) { CPrintf(CON_CMDOUTPUT, "%-25s %-25s %5.1f %-10s %-20s %s\n", reactions[i]->GetEventType(),reactions[i]->GetType().GetDataSafe(), reactions[i]->GetRange(), reactions[i]->GetValue().GetDataSafe(), reactions[i]->GetLastTriggerd().GetDataSafe(), reactions[i]->GetAffectedBehaviors().GetDataSafe()); } }
void psWorld::DumpWarpCache() { for(size_t i=0; i<transarray.GetSize(); i++) { csHash<csReversibleTransform*, csPtrKey<iSector> >::GlobalIterator it = transarray[i].GetIterator(); iSector* fromSector = engine->GetSectors()->Get((int)i); CPrintf(CON_CMDOUTPUT,"%s\n",fromSector->QueryObject()->GetName()); while(it.HasNext()) { csPtrKey<iSector> sector; csReversibleTransform* rt = it.Next(sector); CPrintf(CON_CMDOUTPUT," %-20s : %s\n",sector->QueryObject()->GetName(),toString(*rt).GetData()); } } }
void ShowWarningEntry(char *format,...) { char text[1024]; va_list v; va_start(v, format); vsprintf(text, format, v); SetBackColor(ANSI_BLUE); if (StatusLine > ScrnHeight - 2) { SetForeColor(ANSI_WHITE); ScrollText(); StatusLine--; } SetForeColor(ANSI_RED); MoveCurs(2, StatusLine); CPrintf("$f1*** %s", text); if (logging) { LogFile = fopen("error.log", "a+"); if (LogFile != NULL) CfPrintf(LogFile, "*** %s", text); fclose(LogFile); } StatusLine++; TimeUpdate(); }
void ScrnInit(void) { InitText(); signal(SIGINT, SevereErrorSIGINT); signal(SIGSEGV, SevereErrorSIGSEGV); #ifdef SIGQUIT signal(SIGQUIT, SevereErrorSIGQUIT); #endif LastCheck = StartTime = (long)I_FloatTime(); SetForeColor(ANSI_WHITE); SetBackColor(ANSI_BLUE); DrawFilledBox(0, 0, ScrnWidth, ScrnHeight); StatusLine = 5; MoveCurs(2, 1); SetForeColor(ANSI_WHITE); SetBackColor(ANSI_BLUE); DrawVLine(45, 5, ScrnHeight - 6); DrawHLine(1, 4, ScrnWidth - 2); DrawHLine(1, 2, ScrnWidth - 2); MoveCurs(2, 3); CPrintf("$f3Elapsed time: $f200:00:00 $f7By Lee Smith <[email protected]$f7>$f3"); remove("error.log"); }
void ShowTempEntry(char *format,...) { char text[1024]; va_list v; va_start(v, format); vsprintf(text, format, v); SetBackColor(ANSI_BLUE); if (StatusLine > ScrnHeight - 2) { SetForeColor(ANSI_WHITE); ScrollText(); StatusLine--; } SetForeColor(ANSI_YELLOW); MoveCurs(4, StatusLine); CPrintf("%s", text); StatusLine++; TimeUpdate(); }
void psGameObject::GetPosition(gemNPCObject* object, csVector3& pos, float& yrot,iSector*& sector) { npcMesh * pcmesh = object->pcmesh; // Position if(!pcmesh->GetMesh()) { CPrintf(CON_ERROR,"ERROR! NO MESH FOUND FOR OBJECT %s!\n",object->GetName()); return; } iMovable* npcMovable = pcmesh->GetMesh()->GetMovable(); pos = npcMovable->GetPosition(); // rotation csMatrix3 transf = npcMovable->GetTransform().GetT2O(); yrot = psWorld::Matrix2YRot(transf); if (CS::IsNaN(yrot)) { yrot = 0; } // Sector if (npcMovable->GetSectors()->GetCount()) { sector = npcMovable->GetSectors()->Get(0); } else { sector = NULL; } }
void psGameObject::GetPosition(gemNPCObject* object, csVector3& pos,iSector*& sector) { npcMesh * pcmesh = object->pcmesh; // Position if(!pcmesh->GetMesh()) { CPrintf(CON_ERROR,"ERROR! NO MESH FOUND FOR OBJECT %s!\n",object->GetName()); return; } iMovable* npcMovable = pcmesh->GetMesh()->GetMovable(); pos = npcMovable->GetPosition(); // Sector if (npcMovable->GetSectors()->GetCount()) { sector = npcMovable->GetSectors()->Get(0); } else { sector = NULL; } }
bool LocationType::Load(iDocumentNode* node) { name = node->GetAttributeValue("name"); if(!name.Length()) { CPrintf(CON_ERROR, "Location Types must all have name attributes.\n"); return false; } csRef<iDocumentNodeIterator> iter = node->GetNodes(); while(iter->HasNext()) { csRef<iDocumentNode> node = iter->Next(); if(node->GetType() != CS_NODE_ELEMENT) continue; // This is a widget so read it's factory to create it. if(strcmp(node->GetValue(), "loc") == 0) { Location* newloc = new Location; newloc->pos.x = node->GetAttributeValueAsFloat("x"); newloc->pos.y = node->GetAttributeValueAsFloat("y"); newloc->pos.z = node->GetAttributeValueAsFloat("z"); newloc->rot_angle = node->GetAttributeValueAsFloat("angle"); newloc->radius = node->GetAttributeValueAsFloat("radius"); newloc->sectorName = node->GetAttributeValue("sector"); newloc->type = this; locs.Push(newloc); } } return true; }
bool LocationType::Import(iDocumentNode* node, iDataConnection* db) { name = node->GetAttributeValue("name"); if(!name.Length()) { CPrintf(CON_ERROR, "Location Types must all have name attributes.\n"); return false; } const char* fields[] = {"name"}; psStringArray values; values.Push(name); if(id == -1) { id = db->GenericInsertWithID("sc_location_type",fields,values); if(id == 0) { return false; } } else { csString idStr; idStr.Format("%d",id); return db->GenericUpdateWithID("sc_location_type","id",idStr,fields,values); } return true; }
float ProximityList::RangeTo( gemObject* object, bool ignoreY, bool ignoreInstance) { #ifdef PSPROXDEBUG CPrintf(CON_DEBUG, "[float ProximityList::RangeTo(gemObject* object, bool ignoreY, bool ignoreInstance)]\n"); #endif // If in different instances, except for the common 'all' instance, return a very big value. if (!ignoreInstance && object->GetInstance() != INSTANCE_ALL && self->GetInstance() != INSTANCE_ALL && object->GetInstance() != self->GetInstance()) { return INFINITY_DISTANCE; } // Find the current position of the specified entity csVector3 pos1; csVector3 pos2; iSector *sector1,*sector2; object->GetPosition(pos1,sector1); #ifdef PSPROXDEBUG CPrintf(CON_DEBUG, "Other Entity %s is at (%f,%f,%f)\n", object->GetName(), pos1.x, pos1.y, pos1.z); #endif self->GetPosition(pos2, sector2); #ifdef PSPROXDEBUG CPrintf(CON_DEBUG, "Self Entity %s is at (%f,%f,%f)\n", self->GetName(), pos2.x, pos2.y, pos2.z); #endif if ( ignoreY ) { if(entityManager->GetWorld()->WarpSpace(sector2, sector1, pos2)) { return ( sqrt( (pos1.x - pos2.x)*(pos1.x - pos2.x)+ (pos1.z - pos2.z)*(pos1.z - pos2.z))); } else { return INFINITY_DISTANCE; // No transformation found, so just set larg distance. } } else { return entityManager->GetWorld()->Distance(pos1, sector1, pos2, sector2); } }
void psEndChatLoggingEvent::Trigger() { #ifdef _psEndChatLoggingEvent_DEBUG_ CPrintf(CON_DEBUG, "EndOfChatLoggingEvent is about to happen on clientnum %i!", clientnum); #endif Client *client = NULL; client = psserver->GetConnections()->Find(clientnum); if (!client) { #ifdef _psEndChatLoggingEvent_DEBUG_ CPrintf(CON_DEBUG, "EndOfChatLoggingEvent on unknown client!"); #endif return; } client->GetActor()->RemoveChatReport(); }
psEndChatLoggingEvent::psEndChatLoggingEvent(uint32_t _clientnum, const int delayticks=5000) : psGameEvent(0,delayticks,"psEndChatLoggingEvent") { #ifdef _psEndChatLoggingEvent_DEBUG_ CPrintf(CON_DEBUG, "EndOfChatLoggingEvent created for clientnum %i!", _clientnum); #endif clientnum = _clientnum; }
EID EntityManager::CreateNPC(psCharacter *chardata, InstanceID instance, csVector3 pos, iSector* sector, float yrot, bool updateProxList, bool alwaysWatching) { if (chardata==NULL) return false; // FIXME: This should be an assert elsewhere. psRaceInfo *raceinfo=chardata->GetRaceInfo(); if (raceinfo==NULL) { CPrintf(CON_ERROR, "NPC ID %u: Character Load returned with NULL raceinfo pointer!\n", ShowID(chardata->GetPID())); delete chardata; return false; } gemNPC *actor = new gemNPC(chardata, raceinfo->mesh_name, instance, sector, pos, yrot, 0); actor->SetAlwaysWatching(alwaysWatching); if ( !actor->IsValid() ) { CPrintf(CON_ERROR, "Error while creating Entity for NPC '%s'\n", ShowID(chardata->GetPID())); delete actor; delete chardata; return false; } // This is required to identify all managed npcs. actor->SetSuperclientID( chardata->GetAccount() ); // Add NPC Dialog plugin if any knowledge areas are defined in db for him. actor->SetupDialog(chardata->GetPID(), true); // Setup prox list and send to anyone who needs him if ( updateProxList ) { actor->UpdateProxList( true ); // CPrintf(CON_NOTIFY,"------> Entity Manager Setting Imperv\n"); psserver->npcmanager->ControlNPC( actor ); } Debug3(LOG_NPC, 0, "Created NPC actor: <%s>[%s] in world", actor->GetName(), ShowID(actor->GetEID())); return actor->GetEID(); }
bool LocationManager::Load(iEngine* engine, iDataConnection* db) { Result rs(db->Select("select * from sc_location_type")); if(!rs.IsValid()) { Error2("Could not load locations from db: %s",db->GetLastError()); return false; } for(int i=0; i<(int)rs.Count(); i++) { LocationType* loctype = new LocationType(); if(loctype->Load(rs[i],engine,db)) { loctypes.Put(loctype->name, loctype); CPrintf(CON_DEBUG, "Added location type '%s'(%d)\n",loctype->name.GetDataSafe(),loctype->id); } else { Error2("Could not load location: %s",db->GetLastError()); delete loctype; return false; } } CPrintf(CON_WARNING, "Loaded %d locations \n",rs.Count()); // Create a cache of all the locations. csHash<LocationType*, csString>::GlobalIterator iter(loctypes.GetIterator()); LocationType* loc; while(iter.HasNext()) { loc = iter.Next(); for(size_t i = 0; i < loc->locs.GetSize(); i++) { all_locations.Push(loc->locs[i]); } } return true; }
void psItemSpawnEvent::Trigger() { if(schedule->WantToDie()) return; if(schedule->CreateItem() == NULL) { CPrintf(CON_ERROR,"Couldn't spawn item %u",schedule->GetItemID()); } }
void BehaviorSet::DumpBehaviorList(NPC *npc) { CPrintf(CON_CMDOUTPUT, "Appl. IA %-30s %5s %5s\n","Behavior","Curr","New"); for (size_t i=0; i<behaviors.GetSize(); i++) { char applicable = 'N'; if (npc && behaviors[i]->ApplicableToNPCState(npc)) { applicable = 'Y'; } CPrintf(CON_CMDOUTPUT, "%c %s%s %-30s %5.1f %5.1f\n",applicable, (behaviors[i]->IsInterrupted()?"!":" "), (behaviors[i]->IsActive()?"*":" "), behaviors[i]->GetName(),behaviors[i]->CurrentNeed(), behaviors[i]->NewNeed()); } }
void psNPCLoader::ReadTrainerInfo() { trainerSkills.Empty(); csRef<iDocumentNode> xmlnode = npcRoot->GetNode("trains"); if(!xmlnode) { CPrintf(CON_WARNING, "Warning: no <trains> tag found\n"); return; } csRef<iDocumentNodeIterator> iter = xmlnode->GetNodes("train"); while(iter->HasNext()) { csString skill; int min_rank; int max_rank; int min_faction; csRef<iDocumentNode> trainnode = iter->Next(); skill = trainnode->GetAttributeValue("name"); min_rank = trainnode->GetAttributeValueAsInt("min_rank"); max_rank = trainnode->GetAttributeValueAsInt("max_rank"); min_faction = trainnode->GetAttributeValueAsInt("min_faction"); psSkillInfo* skillInfo = psserver->GetCacheManager()->GetSkillByName(skill); if(skillInfo!=NULL) { psTrainerSkill trainerSkill; trainerSkill.skill = skillInfo; trainerSkill.min_rank = min_rank; trainerSkill.max_rank = max_rank; trainerSkill.min_faction = min_faction; trainerSkills.Push(trainerSkill); } else { CPrintf(CON_WARNING, "Unknown skill for training '%s'... skipping\n",skill.GetData()); } } }
EID EntityManager::CreateNPC(PID npcID, bool updateProxList, bool alwaysWatching) { psCharacter *chardata=psServer::CharacterLoader.LoadCharacterData(npcID,false); if (chardata==NULL) { CPrintf(CON_ERROR, "Couldn't load character for NPC %s.", ShowID(npcID)); return 0; } return CreateNPC(chardata, updateProxList, alwaysWatching); }