예제 #1
0
void Commands::forceRaid(Player& player, const std::string& param)
{
	Raid* raid = Raids::getInstance()->getRaidByName(param);
	if (!raid || !raid->isLoaded()) {
		player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "No such raid exists.");
		return;
	}

	if (Raids::getInstance()->getRunning()) {
		player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Another raid is already being executed.");
		return;
	}

	Raids::getInstance()->setRunning(raid);

	RaidEvent* event = raid->getNextRaidEvent();
	if (!event) {
		player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The raid does not contain any data.");
		return;
	}

	raid->setState(RAIDSTATE_EXECUTING);

	uint32_t ticks = event->getDelay();
	if (ticks > 0) {
		g_scheduler.addEvent(createSchedulerTask(ticks, std::bind(&Raid::executeRaidEvent, raid, event)));
	} else {
		g_dispatcher.addTask(createTask(std::bind(&Raid::executeRaidEvent, raid, event)));
	}

	player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Raid started.");
}
예제 #2
0
bool Raids::loadFromXml()
{
	if (isLoaded()) {
		return true;
	}

	pugi::xml_document doc;
	pugi::xml_parse_result result = doc.load_file("data/raids/raids.xml");
	if (!result) {
		std::cout << "[Error - Raids::loadFromXml] Failed to load data/raids/raids.xml: " << result.description() << std::endl;
		return false;
	}

	for (pugi::xml_node raidNode = doc.child("raids").first_child(); raidNode; raidNode = raidNode.next_sibling()) {
		std::string name, file;
		uint32_t interval, margin;

		pugi::xml_attribute attr;
		if ((attr = raidNode.attribute("name"))) {
			name = attr.as_string();
		} else {
			std::cout << "[Error - Raids::loadFromXml] Name tag missing for raid" << std::endl;
			continue;
		}

		if ((attr = raidNode.attribute("file"))) {
			file = attr.as_string();
		} else {
			std::ostringstream ss;
			ss << "raids/" << name << ".xml";
			file = ss.str();
			std::cout << "[Warning - Raids::loadFromXml] File tag missing for raid " << name << ". Using default: " << file << std::endl;
		}

		interval = pugi::cast<uint32_t>(raidNode.attribute("interval2").value()) * 60;
		if (interval == 0) {
			std::cout << "[Error - Raids::loadFromXml] interval2 tag missing or zero (would divide by 0) for raid: " << name << std::endl;
			continue;
		}

		if ((attr = raidNode.attribute("margin"))) {
			margin = pugi::cast<uint32_t>(attr.value()) * 60 * 1000;
		} else {
			std::cout << "[Warning - Raids::loadFromXml] margin tag missing for raid: " << name << std::endl;
			margin = 0;
		}

		Raid* newRaid = new Raid(name, interval, margin);
		if (newRaid->loadFromXml("data/raids/" + file)) {
			raidList.push_back(newRaid);
		} else {
			std::cout << "[Error - Raids::loadFromXml] Failed to load raid: " << name << std::endl;
			delete newRaid;
		}
	}

	loaded = true;
	return true;
}
예제 #3
0
Mob* HateList::GetDamageTop(Mob* hater)
{
	_ZP(HateList_GetDamageTop);
	Mob* current = NULL;
	Group* grp = NULL;
	Raid* r = NULL;
	uint32 dmg_amt = 0;

    LinkedListIterator<tHateEntry*> iterator(list);
    iterator.Reset();
	while(iterator.MoreElements())
    {
		grp = NULL;
		r = NULL;

		if(iterator.GetData()->ent && iterator.GetData()->ent->IsClient()){
			r = entity_list.GetRaidByClient(iterator.GetData()->ent->CastToClient());
		}

        grp = entity_list.GetGroupByMob(iterator.GetData()->ent);

		if(iterator.GetData()->ent && r){
			if(r->GetTotalRaidDamage(hater) >= dmg_amt)
			{
				current = iterator.GetData()->ent;
				dmg_amt = r->GetTotalRaidDamage(hater);
			}
		}
		else if (iterator.GetData()->ent != NULL && grp != NULL)
        {
			if (grp->GetTotalGroupDamage(hater) >= dmg_amt)
            {
				current = iterator.GetData()->ent;
				dmg_amt = grp->GetTotalGroupDamage(hater);
            }
        }
        else if (iterator.GetData()->ent != NULL && (uint32)iterator.GetData()->damage >= dmg_amt)
        {
			current = iterator.GetData()->ent;
			dmg_amt = iterator.GetData()->damage;
        }
        iterator.Advance();
    }
	return current;
}
예제 #4
0
Mob* HateList::GetDamageTop(Mob* hater)
{
	Mob* current = nullptr;
	Group* grp = nullptr;
	Raid* r = nullptr;
	uint32 dmg_amt = 0;

	auto iterator = list.begin();
	while(iterator != list.end())
	{
		grp = nullptr;
		r = nullptr;

		if((*iterator)->ent && (*iterator)->ent->IsClient()){
			r = entity_list.GetRaidByClient((*iterator)->ent->CastToClient());
		}

		grp = entity_list.GetGroupByMob((*iterator)->ent);

		if((*iterator)->ent && r){
			if(r->GetTotalRaidDamage(hater) >= dmg_amt)
			{
				current = (*iterator)->ent;
				dmg_amt = r->GetTotalRaidDamage(hater);
			}
		}
		else if ((*iterator)->ent != nullptr && grp != nullptr)
		{
			if (grp->GetTotalGroupDamage(hater) >= dmg_amt)
			{
				current = (*iterator)->ent;
				dmg_amt = grp->GetTotalGroupDamage(hater);
			}
		}
		else if ((*iterator)->ent != nullptr && (uint32)(*iterator)->damage >= dmg_amt)
		{
			current = (*iterator)->ent;
			dmg_amt = (*iterator)->damage;
		}
		++iterator;
	}
	return current;
}
예제 #5
0
bool Commands::forceRaid(Creature* creature, const std::string& cmd, const std::string& param)
{
	Player* player = creature->getPlayer();
	if(!player){
		return false;
	}

	Raid* raid = Raids::getInstance()->getRaidByName(param);
	if(!raid || !raid->isLoaded()){
		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "No such raid exists.");
		return false;
	}

	if(Raids::getInstance()->getRunning()){
		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Another raid is already being executed.");
		return false;
	}

	Raids::getInstance()->setRunning(raid);
	RaidEvent* event = raid->getNextRaidEvent();

	if(!event){
		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "The raid does not contain any data.");
		return false;
	}

	raid->setState(RAIDSTATE_EXECUTING);
	uint32_t ticks = event->getDelay();
	if(ticks > 0){
		Scheduler::getScheduler().addEvent(createSchedulerTask(ticks,
			boost::bind(&Raid::executeRaidEvent, raid, event)));
	}
	else{
		Dispatcher::getDispatcher().addTask(createTask(
		boost::bind(&Raid::executeRaidEvent, raid, event)));

	}

	player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Raid started.");
	return true;
}
예제 #6
0
void Raids::checkRaids()
{
	if (!getRunning()) {
		uint64_t now = OTSYS_TIME();

		for (auto it = raidList.begin(); it != raidList.end(); ++it) {
			Raid* raid = *it;
			if (now >= (getLastRaidEnd() + raid->getMargin())) {
				if (MAX_RAND_RANGE * CHECK_RAIDS_INTERVAL / raid->getInterval() >= static_cast<uint32_t>(uniform_random(0, MAX_RAND_RANGE))) {
					setRunning(raid);
					raid->startRaid();

					if (!raid->canBeRepeated()) {
						raidList.erase(it);
					}
					break;
				}
			}
		}
	}

	checkRaidsEvent = g_scheduler.addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this)));
}
예제 #7
0
파일: aa.cpp 프로젝트: af4t/Server
int Client::GroupLeadershipAAHealthRegeneration()
{
	if (IsRaidGrouped()) {
		int bonus = 0;
		Raid *raid = GetRaid();
		if (!raid)
			return 0;
		uint32 group_id = raid->GetGroup(this);
		if (group_id < 12 && raid->GroupCount(group_id) >= 3) {
			switch (raid->GetLeadershipAA(groupAAHealthRegeneration, group_id)) {
			case 1:
				bonus = 4;
				break;
			case 2:
				bonus = 6;
				break;
			case 3:
				bonus = 8;
				break;
			}
		}
		if (raid->RaidCount() >= 18) {
			switch (raid->GetLeadershipAA(raidAAHealthRegeneration)) {
			case 1:
				bonus += 4;
				break;
			case 2:
				bonus += 6;
				break;
			case 3:
				bonus += 8;
				break;
			}
		}
		return bonus;
	}

	Group *g = GetGroup();

	if(!g || (g->GroupCount() < 3))
		return 0;

	switch(g->GetLeadershipAA(groupAAHealthRegeneration))
	{
		case 0:
			return 0;
		case 1:
			return 4;
		case 2:
			return 6;
		case 3:
			return 8;
	}

	return 0;
}
예제 #8
0
파일: aa.cpp 프로젝트: af4t/Server
int Client::GroupLeadershipAAManaEnhancement()
{
	if (IsRaidGrouped()) {
		int bonus = 0;
		Raid *raid = GetRaid();
		if (!raid)
			return 0;
		uint32 group_id = raid->GetGroup(this);
		if (group_id < 12 && raid->GroupCount(group_id) >= 3) {
			switch (raid->GetLeadershipAA(groupAAManaEnhancement, group_id)) {
			case 1:
				bonus = 30;
				break;
			case 2:
				bonus = 60;
				break;
			case 3:
				bonus = 100;
				break;
			}
		}
		if (raid->RaidCount() >= 18) {
			switch (raid->GetLeadershipAA(raidAAManaEnhancement)) {
			case 1:
				bonus += 30;
				break;
			case 2:
				bonus += 60;
				break;
			case 3:
				bonus += 100;
				break;
			}
		}
		return bonus;
	}

	Group *g = GetGroup();

	if(!g || (g->GroupCount() < 3))
		return 0;

	switch(g->GetLeadershipAA(groupAAManaEnhancement))
	{
		case 0:
			return 0;
		case 1:
			return 30;
		case 2:
			return 60;
		case 3:
			return 100;
	}

	return 0;
}
예제 #9
0
파일: corpse.cpp 프로젝트: Zephyr800/Server
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
	/* This gets sent no matter what as a sort of ACK */
	client->QueuePacket(app);

	if (!loot_cooldown_timer.Check()) {
		SendEndLootErrorPacket(client);
		//unlock corpse for others
		if (this->being_looted_by = client->GetID()) {
			being_looted_by = 0xFFFFFFFF;
		}
		return;
	}

	/* To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. */
	if (RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) {
		client->Message(13, "You may not loot an item while you have an item on your cursor.");
		SendEndLootErrorPacket(client);
		/* Unlock corpse for others */
		if (this->being_looted_by = client->GetID()) {
			being_looted_by = 0xFFFFFFFF;
		}
		return;
	}

	LootingItem_Struct* lootitem = (LootingItem_Struct*)app->pBuffer;

	if (this->being_looted_by != client->GetID()) {
		client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client");
		SendEndLootErrorPacket(client);
		return;
	}
	if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) {
		client->Message(13, "Error: This is a player corpse and you dont own it.");
		SendEndLootErrorPacket(client);
		return;
	}
	if (is_locked && client->Admin() < 100) {
		SendLootReqErrorPacket(client, 0);
		client->Message(13, "Error: Corpse locked by GM.");
		return;
	}
	if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) && GetPlayerKillItem() == 0){
		client->Message(13, "Error: You cannot loot any more items from this corpse.");
		SendEndLootErrorPacket(client);
		being_looted_by = 0xFFFFFFFF;
		return;
	}
	const Item_Struct* item = 0;
	ItemInst *inst = 0;
	ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10];

	memset(bag_item_data, 0, sizeof(bag_item_data));
	if (GetPlayerKillItem() > 1){
		item = database.GetItem(GetPlayerKillItem());
	}
	else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1){
		item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward
	}
	else{
		item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN, bag_item_data);
	}

	if (GetPlayerKillItem()<=1 && item_data != 0) {
		item = database.GetItem(item_data->item_id);
	}

	if (item != 0) {
		if (item_data){ 
			inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
		}
		else {
			inst = database.CreateItem(item);
		}
	}

	if (client && inst) {
		if (client->CheckLoreConflict(item)) {
			client->Message_StringID(0, LOOT_LORE_ERROR);
			SendEndLootErrorPacket(client);
			being_looted_by = 0;
			delete inst;
			return;
		}

		if (inst->IsAugmented()) {
			for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
				ItemInst *itm = inst->GetAugment(i);
				if (itm) {
					if (client->CheckLoreConflict(itm->GetItem())) {
						client->Message_StringID(0, LOOT_LORE_ERROR);
						SendEndLootErrorPacket(client);
						being_looted_by = 0;
						delete inst;
						return;
					}
				}
			}
		}

		char buf[88];
		char corpse_name[64];
		strcpy(corpse_name, corpse_name);
		snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name));
		buf[87] = '\0';
		std::vector<EQEmu::Any> args;
		args.push_back(inst);
		args.push_back(this);
		parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
		parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);

		if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) {
			if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
				client->DiscoverItem(inst->GetItem()->ID);
		}

		if (zone->adv_data) {
			ServerZoneAdventureDataReply_Struct *ad = (ServerZoneAdventureDataReply_Struct*)zone->adv_data;
			if (ad->type == Adventure_Collect && !IsPlayerCorpse()) {
				if (ad->data_id == inst->GetItem()->ID) {
					zone->DoAdventureCountIncrease();
				}
			}
		}

		/* First add it to the looter - this will do the bag contents too */
		if (lootitem->auto_loot) {
			if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data))
				client->PutLootInInventory(MainCursor, *inst, bag_item_data);
		}
		else {
			client->PutLootInInventory(MainCursor, *inst, bag_item_data);
		}

		/* Update any tasks that have an activity to loot this item */
		if (RuleB(TaskSystem, EnableTaskSystem))
			client->UpdateTasksForItem(ActivityLoot, item->ID);

		/* Remove it from Corpse */
		if (item_data){
			/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
			database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id);
			/* Delete Item Instance */
			RemoveItem(item_data->lootslot);
		}

		/* Remove Bag Contents */
		if (item->ItemClass == ItemClassContainer && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) {
			for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
				if (bag_item_data[i]) {
					/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
					database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
					/* Delete Item Instance */
					RemoveItem(bag_item_data[i]);
				}
			}
		}

		if (GetPlayerKillItem() != -1) {
			SetPlayerKillItemID(0);
		}

	/* Send message with item link to groups and such */
	Client::TextLink linker;
	linker.SetLinkType(linker.linkItemInst);
	linker.SetItemInst(inst);

	auto item_link = linker.GenerateLink();

	client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());

	if (!IsPlayerCorpse()) {
			Group *g = client->GetGroup();
			if(g != nullptr) {
				g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
			}
			else {
				Raid *r = client->GetRaid();
				if(r != nullptr) {
					r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
				}
			}
		}
	}
	else {
		SendEndLootErrorPacket(client);
		safe_delete(inst);
		return;
	}

	if (IsPlayerCorpse()){
		client->SendItemLink(inst);
	}
	else{
		client->SendItemLink(inst, true);
	}

	safe_delete(inst);
}
예제 #10
0
bool Raids::loadFromXml()
{
	if(isLoaded())
		return true;

	xmlDocPtr doc = xmlParseFile("data/raids/raids.xml");
	if(doc)
	{
		xmlNodePtr root, raidNode;
		root = xmlDocGetRootElement(doc);

		if(xmlStrcmp(root->name,(const xmlChar*)"raids") != 0)
		{
			std::cout << "[Error] Raids: Wrong root node." << std::endl;
			xmlFreeDoc(doc);
			return false;
		}

		int intValue;
		std::string strValue;
		raidNode = root->children;
		while(raidNode)
		{
			if(xmlStrcmp(raidNode->name, (const xmlChar*)"raid") == 0)
			{
				std::string name, file;
				uint32_t interval, margin;

				if(readXMLString(raidNode, "name", strValue))
					name = strValue;
				else
				{
					std::cout << "[Error] Raids: name tag missing for raid." << std::endl;
					raidNode = raidNode->next;
					continue;
				}

				if(readXMLString(raidNode, "file", strValue))
					file = strValue;
				else
				{
					std::ostringstream ss;
					ss << "raids/" << name << ".xml";
					file = ss.str();
					std::cout << "[Warning] Raids: file tag missing for raid " << name << ". Using default: " << file << std::endl;
				}

				//interval2 is the average interval between
				// 2 executions of the raid in minutes
				if(readXMLInteger(raidNode, "interval2", intValue) && intValue > 0)
					interval = intValue * 60;
				else
				{
					std::cout << "[Error] Raids: interval2 tag missing or divided by 0 for raid " << name << std::endl;
					raidNode = raidNode->next;
					continue;
				}

				if(readXMLInteger(raidNode, "margin", intValue))
					margin = intValue * 60 * 1000;
				else
				{
					std::cout << "[Warning] Raids: margin tag missing for raid " << name << std::endl;
					margin = 0;
				}

				Raid* newRaid = new Raid(name, interval, margin);
				if(!newRaid)
				{
					xmlFreeDoc(doc);
					return false;
				}

				bool ret = newRaid->loadFromXml("data/raids/" + file);
				if(!ret)
				{
					std::cout << "[Error] Raids: failed to load raid " << name << std::endl;
					delete newRaid;
				}
				else
					raidList.push_back(newRaid);
			}

			raidNode = raidNode->next;
		}

		xmlFreeDoc(doc);

	}
	else
	{
		std::cout << "[Error] Raids: Could not load data/raids/raids.xml" << std::endl;
		return false;
	}

	loaded = true;
	return true;
}
예제 #11
0
파일: exp.cpp 프로젝트: josheb/emu_dc
void Client::SetLevel(uint8 set_level, bool command)
{
        if (GetEXPForLevel(set_level) == 0xFFFFFFFF) {
                LogFile->write(EQEMuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
                return;
        }

        EQApplicationPacket* outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct));
        LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer;
        lu->level = set_level;
        if(m_pp.level2 != 0)
                lu->level_old = m_pp.level2;
        else
                lu->level_old = level;

        level = set_level;

        if(IsRaidGrouped())
        {
                Raid *r = this->GetRaid();
                if(r){
                        r->UpdateLevel(GetName(), set_level);
                }
        }
        if(set_level > m_pp.level2)
        {
                if(m_pp.level2 == 0)
                        m_pp.points += 5;
                else
                        m_pp.points += (5 * (set_level - m_pp.level2));

                m_pp.level2 = set_level;
        }
        if(set_level > m_pp.level) {
            parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
        }

        m_pp.level = set_level;
        if (command){
                m_pp.exp = GetEXPForLevel(set_level);
                Message(15, "Welcome to level %i!", set_level);
                lu->exp = 0;
        }
        else {
                float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) /
                                                ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
                lu->exp =  (uint32)(330.0f * tmpxp);
    }
        QueuePacket(outapp);
        safe_delete(outapp);
        this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change

		LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);

        CalcBonuses();
        if(!RuleB(Character, HealOnLevel))
        {
                int mhp = CalcMaxHP();
                if(GetHP() > mhp)
                        SetHP(mhp);
        }
        else
        {
                SetHP(CalcMaxHP());             // Why not, lets give them a free heal
        }
		
		DoTributeUpdate();
        SendHPUpdate();
        SetMana(CalcMaxMana());
        UpdateWho();
		if(GetMerc())
			UpdateMercLevel();
        Save();
}
예제 #12
0
파일: raids.cpp 프로젝트: milbradt/TFS
bool Raids::parseRaidNode(xmlNodePtr raidNode, bool checkDuplicate, FileType_t pathing)
{
	if(xmlStrcmp(raidNode->name, (const xmlChar*)"raid"))
		return false;

	int32_t intValue;
	std::string strValue;
	if(!readXMLString(raidNode, "name", strValue))
	{
		std::clog << "[Error - Raids::parseRaidNode] name tag missing for raid." << std::endl;
		return false;
	}

	std::string name = strValue;
	if(!readXMLInteger(raidNode, "interval2", intValue) || intValue <= 0)
	{
		std::clog << "[Error - Raids::parseRaidNode] interval2 tag missing or divided by 0 for raid " << name << std::endl;
		return false;
	}

	uint32_t interval = intValue * 60;
	std::string file;
	if(!readXMLString(raidNode, "file", strValue))
	{
		file = name + ".xml";
		std::clog << "[Warning - Raids::parseRaidNode] file tag missing for raid " << name << ", using default: " << file << std::endl;
	}
	else
		file = strValue;

	file = getFilePath(pathing, "raids/" + file);
	uint64_t margin = 0;
	if(!readXMLInteger(raidNode, "margin", intValue))
		std::clog << "[Warning - Raids::parseRaidNode] margin tag missing for raid " << name << ", using default: " << margin << std::endl;
	else
		margin = intValue * 60 * 1000;

	RefType_t refType = REF_NONE;
	if(readXMLString(raidNode, "reftype", strValue) || readXMLString(raidNode, "refType", strValue))
	{
		std::string tmpStrValue = asLowerCaseString(strValue);
		if(tmpStrValue == "single")
			refType = REF_SINGLE;
		else if(tmpStrValue == "block")
			refType = REF_BLOCK;
		else if(tmpStrValue != "none")
			std::clog << "[Warning - Raids::parseRaidNode] Unknown reftype \"" << strValue << "\" for raid " << name << std::endl;
	}

	bool ref = false;
	if(readXMLString(raidNode, "ref", strValue))
		ref = booleanString(strValue);

	bool enabled = true;
	if(readXMLString(raidNode, "enabled", strValue))
		enabled = booleanString(strValue);

	Raid* raid = new Raid(name, interval, margin, refType, ref, enabled);
	if(!raid || !raid->loadFromXml(file))
	{
		delete raid;
		std::clog << "[Fatal - Raids::parseRaidNode] failed to load raid " << name << std::endl;
		return false;
	}

	if(checkDuplicate)
	{
		for(RaidList::iterator it = raidList.begin(); it != raidList.end(); ++it)
		{
			if((*it)->getName() == name)
				delete *it;
		}
	}

	raidList.push_back(raid);
	return true;
}
예제 #13
0
bool Raids::loadFromXml(const std::string& _filename)
{
	if(isLoaded()){
		return true;
	}

	filename = _filename;

	xmlDocPtr doc = xmlParseFile(filename.c_str());

	if(doc){
		xmlNodePtr root, raidNode;
		root = xmlDocGetRootElement(doc);

		if(xmlStrcmp(root->name,(const xmlChar*)"raids") != 0){
			std::cout << "[Error] Raids: Wrong root node." << std::endl;
			xmlFreeDoc(doc);
			return false;
		}

		int intValue;
		std::string strValue;

		raidNode = root->children;
		while(raidNode){
			if(xmlStrcmp(raidNode->name, (const xmlChar*)"raid") == 0){
				std::string name, file;
				uint32_t interval, margin;

				if(readXMLString(raidNode, "name", strValue)){
					name = strValue;
				}
				else{
					std::cout << "[Error] Raids: name tag missing for raid." << std::endl;
					raidNode = raidNode->next;
					continue;
				}

				if(readXMLString(raidNode, "file", strValue)){
					file = strValue;
				}
				else{
					std::stringstream ss;
					ss << "raids/" << name << ".xml";
					file = ss.str();
					std::cout << "[Warning] Raids: file tag missing for raid " << name << ". Using default: " << file << std::endl;
				}

				//interval2 is the average interval between
				// 2 executions of the raid in minutes
				if(readXMLInteger(raidNode, "interval2", intValue)){
					interval = intValue * 60; //transform  to seconds
				}
				else{
					std::cout << "[Error] Raids: interval2 tag missing for raid " << name << std::endl;
					raidNode = raidNode->next;
					continue;
				}

				if(readXMLInteger(raidNode, "margin", intValue)){
					margin = intValue * 60 * 1000; //transform to milliseconds
				}
				else{
					std::cout << "[Warning] Raids: margin tag missing for raid " << name << std::endl;
					margin = 0;
				}

				Raid* newRaid = new Raid(name, interval, margin);
				if(!newRaid){
					xmlFreeDoc(doc);
					return false;
				}

				bool ret = newRaid->loadFromXml(g_config.getString(ConfigManager::DATA_DIRECTORY) + "raids/" + file);
				if(!ret){
					std::cout << "[Error] Raids: failed to load raid " << name << std::endl;
					delete newRaid;
				}
				else{
					raidList.push_back(newRaid);
				}
			}

			raidNode = raidNode->next;
		}

		xmlFreeDoc(doc);

	}
	else{
		std::cout << "[Error] Raids: Could not load " << filename << std::endl;
		return false;
	}

	loaded = true;
	return true;
}
예제 #14
0
파일: exp.cpp 프로젝트: regneq/Server
void Client::SetLevel(uint8 set_level, bool command)
{
	if (GetEXPForLevel(set_level) == 0xFFFFFFFF) {
		Log.Out(Logs::General, Logs::Error, "Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
		return;
	}

	EQApplicationPacket* outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct));
	LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer;
	lu->level = set_level;
	if(m_pp.level2 != 0)
		lu->level_old = m_pp.level2;
	else
		lu->level_old = level;

	level = set_level;

	if(IsRaidGrouped()) {
		Raid *r = this->GetRaid();
		if(r){
			r->UpdateLevel(GetName(), set_level);
		}
	}
	if(set_level > m_pp.level2) {
		if(m_pp.level2 == 0)
			m_pp.points += 5;
		else
			m_pp.points += (5 * (set_level - m_pp.level2));

		m_pp.level2 = set_level;
	}
	if(set_level > m_pp.level) {
		parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
		/* QS: PlayerLogLevels */
		if (RuleB(QueryServ, PlayerLogLevels)){
			std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
			QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc); 
		}
	}
	else if (set_level < m_pp.level){
		/* QS: PlayerLogLevels */
		if (RuleB(QueryServ, PlayerLogLevels)){
			std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
			QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
		}
	}

	m_pp.level = set_level;
	if (command){
		m_pp.exp = GetEXPForLevel(set_level);
		Message(CC_Yellow, "Welcome to level %i!", set_level);
		lu->exp = 0;
	}
	else {
		float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) / ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
		lu->exp = (uint32)(330.0f * tmpxp);
	}
	QueuePacket(outapp);
	safe_delete(outapp);
	this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change

	Log.Out(Logs::General, Logs::Normal, "Setting Level for %s to %i", GetName(), set_level);

	CalcBonuses();

	if(!RuleB(Character, HealOnLevel)) {
		int mhp = CalcMaxHP();
		if(GetHP() > mhp)
			SetHP(mhp);
	}
	else {
		SetHP(CalcMaxHP()); // Why not, lets give them a free heal
	}
	if(!RuleB(Character, ManaOnLevel))
	{
		int mp = CalcMaxMana();
		if(GetMana() > mp)
			SetMana(mp);
	}
	else
	{
		SetMana(CalcMaxMana()); // Why not, lets give them a free heal
	}

	SendHPUpdate();
	SendManaUpdate();
	UpdateWho();
	Save();
}
예제 #15
0
파일: exp.cpp 프로젝트: artemyse/Server
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {

	this->EVENT_ITEM_ScriptStopReturn();

	uint32 add_exp = in_add_exp;

	if(!resexp && (XPRate != 0))
		add_exp = static_cast<uint32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));

	if (m_epp.perAA<0 || m_epp.perAA>100)
		m_epp.perAA=0;	// stop exploit with sanity check

	uint32 add_aaxp;
	if(resexp) {
		add_aaxp = 0;
	} else {

		//figure out how much of this goes to AAs
		add_aaxp = add_exp * m_epp.perAA / 100;
		//take that ammount away from regular exp
		add_exp -= add_aaxp;

		float totalmod = 1.0;
		float zemmod = 1.0;
		//get modifiers
		if(RuleR(Character, ExpMultiplier) >= 0){
			totalmod *= RuleR(Character, ExpMultiplier);
		}

		if(zone->newzone_data.zone_exp_multiplier >= 0){
			zemmod *= zone->newzone_data.zone_exp_multiplier;
		}

		if(RuleB(Character,UseRaceClassExpBonuses))
		{
			if(GetBaseRace() == HALFLING){
				totalmod *= 1.05;
			}

			if(GetClass() == ROGUE || GetClass() == WARRIOR){
				totalmod *= 1.05;
			}
		}

		if(zone->IsHotzone())
		{
			totalmod += RuleR(Zone, HotZoneBonus);
		}

		add_exp = uint32(float(add_exp) * totalmod * zemmod);

		if(RuleB(Character,UseXPConScaling))
		{
			if (conlevel != 0xFF && !resexp) {
				switch (conlevel)
				{
					case CON_GREEN:
						add_exp = 0;
						add_aaxp = 0;
						return;
					case CON_LIGHTBLUE:
							add_exp = add_exp * RuleI(Character, LightBlueModifier)/100;
							add_aaxp = add_aaxp * RuleI(Character, LightBlueModifier)/100;
						break;
					case CON_BLUE:
							add_exp = add_exp * RuleI(Character, BlueModifier)/100;
							add_aaxp = add_aaxp * RuleI(Character, BlueModifier)/100;
						break;
					case CON_WHITE:
							add_exp = add_exp * RuleI(Character, WhiteModifier)/100;
							add_aaxp = add_aaxp * RuleI(Character, WhiteModifier)/100;
						break;
					case CON_YELLOW:
							add_exp = add_exp * RuleI(Character, YellowModifier)/100;
							add_aaxp = add_aaxp * RuleI(Character, YellowModifier)/100;
						break;
					case CON_RED:
							add_exp = add_exp * RuleI(Character, RedModifier)/100;
							add_aaxp = add_aaxp * RuleI(Character, RedModifier)/100;
						break;
				}
			}
		}

		if (IsLeadershipEXPOn() && (conlevel == CON_BLUE || conlevel == CON_WHITE || conlevel == CON_YELLOW || conlevel == CON_RED)) {
			add_exp = static_cast<uint32>(static_cast<float>(add_exp) * 0.8f);

			if (GetGroup()) {
				if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
						&& RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
					uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
					Client *mentoree = GetGroup()->GetMentoree();
					if (GetGroup()->GetMentorPercent() && mentoree &&
							mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
						uint32 mentor_exp = exp * (GetGroup()->GetMentorPercent() / 100.0f);
						exp -= mentor_exp;
						mentoree->AddLeadershipEXP(mentor_exp, 0); // ends up rounded down
						mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
					}
					if (exp > 0) { // possible if you mentor 100% to the other client
						AddLeadershipEXP(exp, 0); // ends up rounded up if mentored, no idea how live actually does it
						Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
					}
				} else {
					Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
				}
			} else {
				Raid *raid = GetRaid();
				// Raid leaders CAN NOT gain group AA XP, other group leaders can though!
				if (raid->IsLeader(this)) {
					if (m_pp.raid_leadership_points < MaxBankedRaidLeadershipPoints(GetLevel())
							&& RuleI(Character, KillsPerRaidLeadershipAA) > 0) {
						AddLeadershipEXP(0, RAID_EXP_PER_POINT / RuleI(Character, KillsPerRaidLeadershipAA));
						Message_StringID(MT_Leadership, GAIN_RAID_LEADERSHIP_EXP);
					} else {
						Message_StringID(MT_Leadership, MAX_RAID_LEADERSHIP_POINTS);
					}
				} else {
					if (m_pp.group_leadership_points < MaxBankedGroupLeadershipPoints(GetLevel())
							&& RuleI(Character, KillsPerGroupLeadershipAA) > 0) {
						uint32 group_id = raid->GetGroup(this);
						uint32 exp = GROUP_EXP_PER_POINT / RuleI(Character, KillsPerGroupLeadershipAA);
						Client *mentoree = raid->GetMentoree(group_id);
						if (raid->GetMentorPercent(group_id) && mentoree &&
								mentoree->GetGroupPoints() < MaxBankedGroupLeadershipPoints(mentoree->GetLevel())) {
							uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f);
							exp -= mentor_exp;
							mentoree->AddLeadershipEXP(mentor_exp, 0);
							mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
						}
						if (exp > 0) {
							AddLeadershipEXP(exp, 0);
							Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP);
						}
					} else {
						Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS);
					}
				}
			}

		}

	}	//end !resexp

	float aatotalmod = 1.0;
	if(zone->newzone_data.zone_exp_multiplier >= 0){
		aatotalmod *= zone->newzone_data.zone_exp_multiplier;
	}



	if(RuleB(Character,UseRaceClassExpBonuses))
	{
		if(GetBaseRace() == HALFLING){
			aatotalmod *= 1.05;
		}

		if(GetClass() == ROGUE || GetClass() == WARRIOR){
			aatotalmod *= 1.05;
		}
	}

	if(RuleB(Zone, LevelBasedEXPMods)){
		if(zone->level_exp_mod[GetLevel()].ExpMod){
			add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
			add_aaxp *= zone->level_exp_mod[GetLevel()].AAExpMod;
		}
	}

	uint32 exp = GetEXP() + add_exp;

	uint32 aaexp = (uint32)(RuleR(Character, AAExpMultiplier) * add_aaxp * aatotalmod);
	uint32 had_aaexp = GetAAXP();
	aaexp += had_aaexp;
	if(aaexp < had_aaexp)
		aaexp = had_aaexp;	//watch for wrap

	SetEXP(exp, aaexp, resexp);
}