コード例 #1
0
/**
 * @brief Compute the next itemID
 * @note If something found, item type can be find with iterator->itemID
 * @note If item is available into the container iterator->itemFound point to this element
 * @note If nothing found (no next element) then iterator->itemID >= csi.numODs
 */
static void UI_ContainerItemIteratorNext (containerItemIterator_t* iterator)
{
	assert(iterator->groupSteps[iterator->groupID] != CII_END);

	/* iterate each groups */
	for (; iterator->groupSteps[iterator->groupID] != CII_END; iterator->groupID++) {
		int filter = iterator->groupSteps[iterator->groupID];
		/* next */
		iterator->itemID++;

		/* iterate all item type*/
		for (;iterator->itemID < csi.numODs; iterator->itemID++) {
			const objDef_t* obj = INVSH_GetItemByIDX(iterator->itemID);

			/* gameplay filter */
			if (!GAME_ItemIsUseable(obj))
				continue;

			/* type filter */
			/** @todo not sure its the right check */
			const bool isArmour = obj->isArmour();
			const bool isAmmo = obj->numWeapons != 0 && obj->isAmmo();
			const bool isWeapon = obj->weapon || obj->isMisc || isArmour;
			const bool isImplant = obj->implant;

			if ((filter & CII_WEAPONONLY) && !isWeapon)
				continue;
			if ((filter & CII_AMMOONLY) && !isAmmo)
				continue;
			if ((filter & CII_IMPLANTONLY) && !isImplant)
				continue;
			if (!INV_ItemMatchesFilter(obj, iterator->filterEquipType))
				continue;

			/* exists in inventory filter */
			iterator->itemFound = UI_ContainerNodeGetExistingItem(iterator->node, obj, iterator->filterEquipType);
			if ((filter & CII_AVAILABLEONLY) && iterator->itemFound == nullptr)
				continue;
			if ((filter & CII_NOTAVAILABLEONLY) && iterator->itemFound != nullptr)
				continue;

			/* we found something */
			return;
		}

		/* can we search into another group? */
		if (iterator->groupSteps[iterator->groupID + 1] != CII_END)
			iterator->itemID = -1;
	}

	/* clean up */
	iterator->itemFound = nullptr;
}
コード例 #2
0
/**
 * @note this function is a copy-paste of UI_ContainerNodeDrawItems (with remove of unneeded code)
 */
static Item* UI_BaseInventoryNodeGetItem (const uiNode_t* const node, int mouseX, int mouseY, int* contX, int* contY)
{
	bool outOfNode = false;
	vec2_t nodepos;
	int items = 0;
	int rowHeight = 0;
	const int cellWidth = node->box.size[0] / EXTRADATACONST(node).columns;
	int tempX, tempY;
	containerItemIterator_t iterator;
	int currentHeight = 0;

	if (!contX)
		contX = &tempX;
	if (!contY)
		contY = &tempY;

	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);
		vec2_t pos;
		vec2_t ammopos;
		const int col = items % EXTRADATACONST(node).columns;
		int cellHeight = 0;
		Item* icItem = iterator.itemFound;
		int height;

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

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

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

		/* check item */
		if (mouseY < pos[1])
			break;
		if (mouseX >= pos[0] && mouseX < pos[0] + obj->sx * C_UNIT
		 && mouseY >= pos[1] && mouseY < pos[1] + obj->sy * C_UNIT) {
			if (icItem) {
				*contX = icItem->getX();
				*contY = icItem->getY();
				return icItem;
			}
			return nullptr;
		}
		pos[1] += obj->sy * C_UNIT;
		cellHeight += obj->sy * C_UNIT;

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

		/* draw the item name. */
		R_FontTextSize("f_verysmall", _(obj->name),
			cellWidth - 5, LONGLINES_WRAP, nullptr, &height, nullptr, nullptr);
		cellHeight += height;

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

				/* skip unusable ammo */
				if (!GAME_ItemIsUseable(objammo))
					continue;

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

				/* check ammo (ammopos in on the left-lower corner) */
				if (mouseX < ammopos[0] || mouseY >= ammopos[1])
					break;
				if (mouseX >= ammopos[0] && mouseX < ammopos[0] + objammo->sx * C_UNIT
				 && mouseY >= ammopos[1] - objammo->sy * C_UNIT && mouseY < ammopos[1]) {
					*contX = icItem->getX();
					*contY = icItem->getY();
					return icItem;
				}
				ammopos[0] += objammo->sx * C_UNIT;
			}
		}
		cellHeight += 10;

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

		/* add a margin between rows */
		if (col == EXTRADATACONST(node).columns - 1) {
			currentHeight += rowHeight;
			rowHeight = 0;
			if (currentHeight - EXTRADATACONST(node).scrollY.viewPos >= node->box.size[1])
				return nullptr;
		}

		/* count items */
		items++;
	}

	*contX = NONE;
	*contY = NONE;
	return nullptr;
}
コード例 #3
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;
}
コード例 #4
0
ファイル: ui_node_container.cpp プロジェクト: jklemmack/ufoai
/**
 * @brief Call into the source when the DND end
 */
bool uiContainerNode::onDndFinished (uiNode_t *source, bool isDropped)
{
	item_t *dragItem = UI_DNDGetItem();
	const invDef_t *sourceContainer = EXTRADATACONST(source).container;

	/* if the target can't finalize the DND we stop */
	if (!isDropped) {
		return false;
	}

	assert(sourceContainer);

	/* on tactical mission */
	if (CL_BattlescapeRunning()) {
		const uiNode_t *target = UI_DNDGetTargetNode();
		const invDef_t *targetContainer = EXTRADATACONST(target).container;
		assert(targetContainer);
		CL_ActorInvMove(selActor, sourceContainer->id, dragInfoFromX, dragInfoFromY,
				targetContainer->id, dragInfoToX, dragInfoToY);
	} else {
		uiNode_t *target = UI_DNDGetTargetNode();
		if (target) {
			invList_t *fItem;
			invList_t *tItem;
			bool moved = false;
			const invDef_t *targetContainer = EXTRADATACONST(target).container;
			assert(targetContainer);
			if (UI_IsScrollContainerNode(source)) {
				fItem = UI_ContainerNodeGetExistingItem(sourceContainer, dragItem->item, MAX_FILTERTYPES);
			} else
				fItem = INVSH_SearchInInventory(ui_inventory, sourceContainer, dragInfoFromX, dragInfoFromY);
			assert(fItem);

			/** @todo We must split the move in two. Here, we should not know how to add the item to the target (see dndDrop) */
			/* Remove ammo on removing weapon from a soldier */
			if (UI_IsScrollContainerNode(target) && fItem->item.ammo && fItem->item.ammo != fItem->item.item && fItem->item.ammoLeft)
				INV_UnloadWeapon(fItem, ui_inventory, targetContainer);

			/* rotate on Shift */
			/** @todo enable Shift-rotate for battlescape too when issues are solved */
			fItem->item.rotated = Key_IsDown(K_SHIFT) && !CL_BattlescapeRunning();

			/* move the item */
			moved = INV_MoveItem(ui_inventory, targetContainer, dragInfoToX, dragInfoToY, sourceContainer, fItem, &tItem);

			/* No need to continue move wasn't successful */
			if (!moved)
				return false;

			/* Add ammo on adding weapon to a soldier */
			if (UI_IsScrollContainerNode(source) && ((fItem->item.item->weapon && !fItem->item.ammoLeft) || fItem->item.item->oneshot))
				INV_LoadWeapon(tItem, ui_inventory, sourceContainer, targetContainer);

			/* Run onChange events */
			if (source->onChange)
				UI_ExecuteEventActions(source, source->onChange);
			if (source != target && target->onChange)
				UI_ExecuteEventActions(target, target->onChange);
		}
	}

	dragInfoFromX = -1;
	dragInfoFromY = -1;
	return true;
}