Exemplo n.º 1
0
// -------- begin of function ItemRes::can_equip ----------//
//
int ItemRes::can_equip( short itemId, int unitId, Skill &skill )
{
	if( !itemId )
		return 0;

	if( !unit_res[unitId]->race_id || unitId == UNIT_WAGON )		// only human or monster can equip
		return 0;

	err_when( itemId > ITEM_TYPE_COUNT );

	// if an item has ITEM_ABILITY_ARROW_DAMAGE but no ITEM_ABILITY_DAMAGE
	// it must be wear by an archer unit

	Item tempItem( itemId, 0 );
	if( ability( tempItem, ITEM_ABILITY_ARROW_DAMAGE) > 0
		&& ability( tempItem, ITEM_ABILITY_DAMAGE) == 0 )
	{
		// find unit attack record to see if any range attack

		int canRangeAttack = 0;
		UnitInfo *unitInfo = unit_res[unitId];
		for( int curAttack = unitInfo->attack_count-1; curAttack >= 0; --curAttack )
		{
			AttackInfo *attackInfo = 
				unit_res.get_attack_info( unitInfo->first_attack + curAttack );
			if( attackInfo->attack_range > 1 
				&& skill.actual_skill_level(NULL) >= attackInfo->combat_level )
			{
				canRangeAttack = 1;
			}
		}

		if( !canRangeAttack )
			return 0;
	}

	return 1;
}
Exemplo n.º 2
0
/**
 * @brief Draw the base inventory
 * @return The full height requested by the current view (not the node height)
 */
static int UI_BaseInventoryNodeDrawItems (uiNode_t* node, const objDef_t* highlightType)
{
	bool outOfNode = false;
	vec2_t nodepos;
	int items = 0;
	int rowHeight = 0;
	const int cellWidth = node->box.size[0] / EXTRADATA(node).columns;
	containerItemIterator_t iterator;
	int currentHeight = 0;
	UI_GetNodeAbsPos(node, nodepos);

	UI_ContainerItemIteratorInit(&iterator, node);
	for (; iterator.itemID < csi.numODs; UI_ContainerItemIteratorNext(&iterator)) {
		const int id = iterator.itemID;
		const objDef_t* obj = INVSH_GetItemByIDX(id);
		Item tempItem(obj, nullptr, 1);
		vec3_t pos;
		vec3_t ammopos;
		const float* color;
		bool isHighlight = false;
		int amount;
		const int col = items % EXTRADATA(node).columns;
		int cellHeight = 0;
		const Item* icItem = iterator.itemFound;

		/* skip items over and bellow the node view */
		if (outOfNode || currentHeight < EXTRADATA(node).scrollY.viewPos) {
			int height;
			R_FontTextSize("f_verysmall", _(obj->name),
				cellWidth - 5, LONGLINES_WRAP, nullptr, &height, nullptr, nullptr);
			height += obj->sy * C_UNIT + 10;
			if (height > rowHeight)
				rowHeight = height;

			if (outOfNode || currentHeight + rowHeight < EXTRADATA(node).scrollY.viewPos) {
				if (col == EXTRADATA(node).columns - 1) {
					currentHeight += rowHeight;
					rowHeight = 0;
				}
				items++;
				continue;
			}
		}

		Vector2Copy(nodepos, pos);
		pos[0] += cellWidth * col;
		pos[1] += currentHeight - EXTRADATA(node).scrollY.viewPos;
		pos[2] = 0;

		if (highlightType) {
			if (obj->isAmmo())
				isHighlight = obj->isLoadableInWeapon(highlightType);
			else
				isHighlight = highlightType->isLoadableInWeapon(obj);
		}

		if (icItem != nullptr) {
			if (isHighlight)
				color = colorLoadable;
			else
				color = colorDefault;
		} else {
			if (isHighlight)
				color = colorDisabledLoadable;
			else
				color = colorDisabledHiden;
		}

		if (icItem)
			amount = icItem->getAmount();
		else
			amount = 0;

		/* draw item */
		pos[0] += obj->sx * C_UNIT / 2.0;
		pos[1] += obj->sy * C_UNIT / 2.0;
		UI_DrawItem(node, pos, &tempItem, -1, -1, scale, color);
		UI_DrawString("f_verysmall", ALIGN_LC,
			pos[0] + obj->sx * C_UNIT / 2.0, pos[1] + obj->sy * C_UNIT / 2.0,
			pos[0] + obj->sx * C_UNIT / 2.0, cellWidth - 5, /* maxWidth */
			0, va("x%i", amount));
		pos[0] -= obj->sx * C_UNIT / 2.0;
		pos[1] += obj->sy * C_UNIT / 2.0;
		cellHeight += obj->sy * C_UNIT;

		/* save position for ammo */
		Vector2Copy(pos, ammopos);
		ammopos[2] = 0;
		ammopos[0] += obj->sx * C_UNIT + 10;

		/* draw the item name. */
		cellHeight += UI_DrawString("f_verysmall", ALIGN_UL,
			pos[0], pos[1],
			pos[0], cellWidth - 5, /* max width */
			0, _(obj->name));

		/* draw ammos of weapon */
		if (obj->weapon && EXTRADATA(node).displayAmmoOfWeapon) {
			for (int ammoIdx = 0; ammoIdx < obj->numAmmos; ammoIdx++) {
				tempItem.setDef(obj->ammos[ammoIdx]);

				/* skip weapos that are their own ammo -- oneshot and such */
				if (obj == tempItem.def())
					continue;

				/* skip unusable ammo */
				if (!GAME_ItemIsUseable(tempItem.def()))
					continue;

				/* find and skip none existing ammo */
				icItem = UI_ContainerNodeGetExistingItem(node, tempItem.def(), (itemFilterTypes_t) EXTRADATA(node).filterEquipType);
				if (!icItem)
					continue;

				/* Calculate the center of the item model/image. */
				ammopos[0] += icItem->def()->sx * C_UNIT / 2.0;
				ammopos[1] -= icItem->def()->sy * C_UNIT / 2.0;
				UI_DrawItem(node, ammopos, &tempItem, -1, -1, scale, colorDefault);
				UI_DrawString("f_verysmall", ALIGN_LC,
					ammopos[0] + icItem->def()->sx * C_UNIT / 2.0, ammopos[1] + icItem->def()->sy * C_UNIT / 2.0,
					ammopos[0] + icItem->def()->sx * C_UNIT / 2.0, cellWidth - 5 - ammopos[0],	/* maxWidth */
					0, va("x%i", icItem->getAmount()));
				ammopos[0] += icItem->def()->sx * C_UNIT / 2.0;
				ammopos[1] += icItem->def()->sy * C_UNIT / 2.0;
			}
		}
		cellHeight += 10;

		if (cellHeight > rowHeight) {
			rowHeight = cellHeight;
		}

		/* add a marge between rows */
		if (col == EXTRADATA(node).columns - 1) {
			currentHeight += rowHeight;
			rowHeight = 0;
			if (currentHeight - EXTRADATA(node).scrollY.viewPos >= node->box.size[1])
				outOfNode = true;
		}

		/* count items */
		items++;
	}

	if (rowHeight != 0) {
		currentHeight += rowHeight;
	}
	return currentHeight;
}