Beispiel #1
0
/**
 * Enemies that drop loot raise a "loot_drop" flag to notify this loot
 * manager to create loot based on that creature's level and position.
 */
void LootManager::checkEnemiesForLoot() {
	ItemStack istack;
	istack.quantity = 1;
	
	for (int i=0; i<enemies->enemy_count; i++) {
		if (enemies->enemies[i]->loot_drop) {
			
			if (enemies->enemies[i]->stats.quest_loot_id != 0) {				
				// quest loot
				istack.item = enemies->enemies[i]->stats.quest_loot_id;
				addLoot(istack, enemies->enemies[i]->stats.pos);
			}
			else {
				// random loot
				determineLoot(enemies->enemies[i]->stats.level, enemies->enemies[i]->stats.pos);
			}
			
			enemies->enemies[i]->loot_drop = false;
		}
	}
}
Beispiel #2
0
/**
 * As map events occur, some might have a component named "loot"
 * Loot is created at component x,y
 */
void LootManager::checkMapForLoot() {
	Point p;
	Event_Component *ec;
	ItemStack loot;
	
	while (!map->loot.empty()) {
		ec = &map->loot.front();
		p.x = ec->x;
		p.y = ec->y;
		
		if (ec->s == "random") {
			determineLoot(ec->z, p);
		}
		else if (ec->s == "id") {
			loot.item = ec->z;
			loot.quantity = 1;
			addLoot(loot, p);
		}
		else if (ec->s == "currency") {
			addGold(ec->z, p);
		}
		map->loot.pop();
	}
}
Beispiel #3
0
void LootManager::checkLoot(std::vector<Event_Component> &loot_table, FPoint *pos) {
	if (hero == NULL) {
		logError("LootManager: checkLoot() failed, no hero.");
		return;
	}

	FPoint p;
	Event_Component *ec;
	ItemStack new_loot;
	std::vector<Event_Component*> possible_ids;

	int chance = rand() % 100;

	// first drop any 'fixed' (0% chance) items
	for (size_t i = loot_table.size(); i > 0; i--) {
		ec = &loot_table[i-1];
		if (ec->z == 0) {
			Point src;
			if (pos) {
				src = floor(*pos);
			}
			else {
				src.x = ec->x;
				src.y = ec->y;
			}
			p = mapr->collider.get_random_neighbor(src, drop_radius);

			if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) {
				p = hero->pos;
			}
			else {
				if (src.x == p.x && src.y == p.y)
					p = hero->pos;

				mapr->collider.block(p.x, p.y, false);
				tiles_to_unblock.push_back(floor(p));
			}

			new_loot.quantity = randBetween(ec->a,ec->b);

			// an item id of 0 means we should drop currency instead
			if (ec->c == 0 || ec->c == CURRENCY_ID) {
				new_loot.item = CURRENCY_ID;
				new_loot.quantity = new_loot.quantity * (100 + hero->get(STAT_CURRENCY_FIND)) / 100;
			}
			else {
				new_loot.item = ec->c;
			}

			addLoot(new_loot, p);

			loot_table.erase(loot_table.begin()+i-1);
		}
	}

	// now pick up to 1 random item to drop
	int threshold = hero->get(STAT_ITEM_FIND) + 100;
	for (unsigned i = 0; i < loot_table.size(); i++) {
		ec = &loot_table[i];

		int real_chance = ec->z;

		if (ec->c != 0 && ec->c != CURRENCY_ID) {
			real_chance = static_cast<int>(static_cast<float>(ec->z) * static_cast<float>(hero->get(STAT_ITEM_FIND) + 100) / 100.f);
		}

		if (real_chance >= chance) {
			if (real_chance <= threshold) {
				if (real_chance != threshold) {
					possible_ids.clear();
				}

				threshold = real_chance;
			}

			if (chance <= threshold) {
				possible_ids.push_back(ec);
			}
		}
	}

	if (!possible_ids.empty()) {
		// if there was more than one item with the same chance, randomly pick one of them
		size_t chosen_loot = static_cast<size_t>(rand()) % possible_ids.size();

		ec = possible_ids[chosen_loot];

		Point src;
		if (pos) {
			src = floor(*pos);
		}
		else {
			src.x = ec->x;
			src.y = ec->y;
		}
		p = mapr->collider.get_random_neighbor(src, drop_radius);

		if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) {
			p = hero->pos;
		}
		else {
			if (src.x == p.x && src.y == p.y)
				p = hero->pos;

			mapr->collider.block(p.x, p.y, false);
			tiles_to_unblock.push_back(floor(p));
		}

		new_loot.quantity = randBetween(ec->a,ec->b);

		// an item id of 0 means we should drop currency instead
		if (ec->c == 0 || ec->c == CURRENCY_ID) {
			new_loot.item = CURRENCY_ID;
			new_loot.quantity = new_loot.quantity * (100 + hero->get(STAT_CURRENCY_FIND)) / 100;
		}
		else {
			new_loot.item = ec->c;
		}

		addLoot(new_loot, p);
	}
}