static void activate(int val) { Entity *e; if (self->health == 3) { e = addTeslaPack(0, 0, "item/tesla_pack_full"); addToInventory(e); self->health = -1; } else { e = getInventoryItemByObjectiveName("Tesla Pack"); if (e != NULL && e->health == 0) { removeInventoryItemByObjectiveName(e->objectiveName); self->health = 0; self->thinkTime = 180; } } setChargeState(); }
void ControlSystem::pickUpItem() const { if (player_turn_->turn_taken) { return; } GameObject item = getItemAtPos(player_space_->pos); if (item.getId()) { addToInventory(item); } }
static void addStatue(int val) { Entity *e; if (self->target == NULL) { e = getCurrentInventoryItem(); if (e == NULL || strstr(e->name, "_statue") == NULL) { runScript("statue_required"); } else { STRNCPY(self->objectiveName, e->objectiveName, sizeof(e->objectiveName)); e = addEntity(*e, self->x, self->y); self->target = e; self->target->x = self->x + self->w / 2; self->target->x -= self->target->w / 2; self->target->y = self->y - self->target->h; self->target->flags |= FLY; self->target->touch = NULL; self->target->action = &statueWait; removeInventoryItemByObjectiveName(e->objectiveName); validate(); } } else { e = addEntity(*self->target, 0, 0); addToInventory(e); self->target->inUse = FALSE; self->target = NULL; self->objectiveName[0] = '\0'; } }
static void collectBomb(Entity *other) { Entity *bomb = NULL; if (other->type == PLAYER && self->thinkTime <= 0 && other->health > 0) { if (getInventoryItemByObjectiveName("Bomb") == NULL) { bomb = addBomb(other->x, other->y, "item/bomb"); STRNCPY(bomb->objectiveName, "Bomb", sizeof(bomb->objectiveName)); addToInventory(bomb); } self->thinkTime = self->maxThinkTime; } }
static void collectSpore(Entity *other) { Entity *spore = NULL; if (self->thinkTime <= 0 && other->health > 0) { if (getInventoryItemByObjectiveName("Spore") == NULL) { spore = addSpore(other->x, other->y, "item/spores"); STRNCPY(spore->objectiveName, "Spore", sizeof(spore->objectiveName)); addToInventory(spore); } self->thinkTime = self->maxThinkTime; } }
/** * @brief Tries to add an item to a container (in the inventory inv). * @param[in] inv The inventory to add the item to. * @param[in] item Item to add to inventory (actually a copy of it). * @param[in] container Container id. * @sa findSpace * @sa addToInventory */ bool InventoryInterface::tryAddToInventory (Inventory* const inv, const Item* const item, const invDef_t* container) { int x, y; inv->findSpace(container, item, &x, &y, nullptr); if (x == NONE) { assert(y == NONE); return false; } else { const int checkedTo = inv->canHoldItem(container, item->def(), x, y, nullptr); if (!checkedTo) return false; const bool rotated = checkedTo == INV_FITS_ONLY_ROTATED; Item itemRotation = *item; itemRotation.rotated = rotated; return addToInventory(inv, &itemRotation, container, x, y, 1) != nullptr; } }
void Hero::search() { std::cout << "Items:\n"; if (location->getItems().size() == 0) std::cout << "The room is empty\n\n"; else { std::cout << "You found: "; bool hasPrev = false; // temp display for (Item* item : location->getItems()) { if (hasPrev) cout << ", "; std::cout << item->getName(); addToInventory(item); hasPrev = true; } std::cout << std::endl << std::endl; } addPerception(1); }
char *loadResources(char *buffer) { int i, startX, startY, type, name, resourceType; char *token, *line, itemName[MAX_VALUE_LENGTH], *savePtr2, *savePtr; Entity *e; savePtr = NULL; resourceType = ENTITY_DATA; if (key == NULL || value == NULL) { key = malloc(sizeof(char *) * MAX_PROPS_FILES); value = malloc(sizeof(char *) * MAX_PROPS_FILES); if (key == NULL || value == NULL) { showErrorAndExit("Ran out of memory when loading properties"); } for (i=0;i<MAX_PROPS_FILES;i++) { key[i] = malloc(MAX_VALUE_LENGTH); value[i] = malloc(MAX_VALUE_LENGTH); if (key[i] == NULL || value[i] == NULL) { showErrorAndExit("Ran out of memory when loading properties"); } } } for (i=0;i<MAX_PROPS_FILES;i++) { key[i][0] = '\0'; value[i][0] = '\0'; } i = 0; name = type = startX = startY = -1; e = NULL; line = strtok_r(buffer, "\n", &savePtr); while (line != NULL) { if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } if (line[strlen(line) - 1] == '\r') { line[strlen(line) - 1] = '\0'; } if (line[0] == '#' || line[0] == '\n') { line = strtok_r(NULL, "\n", &savePtr); continue; } else if (line[0] == ' ') { printf("WARNING: Line starts with a space\n"); #if DEV == 1 exit(0); #endif line = strtok_r(NULL, "\n", &savePtr); continue; } sscanf(line, "%s", itemName); if (strcmpignorecase(itemName, "MAP_NAME") == 0) { break; } else if (strcmpignorecase(itemName, "UPDATE_ENTITY") == 0 || strcmpignorecase(itemName, "REMOVE_ENTITY") == 0) { break; } else if (strcmpignorecase(line, "PLAYER_INVENTORY") == 0) { resourceType = PLAYER_INVENTORY; } else if (strstr(line, "INVENTORY_INDEX") != NULL) { sscanf(line, "%*s %d", &startX); setInventoryIndex(startX); } else if (strcmpignorecase(line, "ENTITY_DATA") == 0) { resourceType = ENTITY_DATA; } else if (strcmpignorecase(line, "{") == 0) { i = 0; name = type = startX = startY = -1; e = NULL; } else if (strcmpignorecase(line, "}") == 0) { e = addEntityFromResource(value[type], value[name], startX == -1 ? 0 : atoi(value[startX]), startY == -1 ? 0 : atoi(value[startY])); if (e != NULL) { for (i=0;i<MAX_PROPS_FILES;i++) { if (strlen(key[i]) > 0) { setProperty(e, key[i], value[i]); } } if (resourceType == PLAYER_INVENTORY) { addToInventory(e); } } for (i=0;i<MAX_PROPS_FILES;i++) { key[i][0] = '\0'; value[i][0] = '\0'; } i = 0; } else { token = strtok_r(line, " ", &savePtr2); STRNCPY(key[i], token, MAX_VALUE_LENGTH); token = strtok_r(NULL, "\0", &savePtr2); if (token != NULL) { STRNCPY(value[i], token, MAX_VALUE_LENGTH); } else { key[i][0] = '\0'; } if (strcmpignorecase(key[i], "TYPE") == 0) { type = i; } else if (strcmpignorecase(key[i], "START_X") == 0) { startX = i; } else if (strcmpignorecase(key[i], "START_Y") == 0) { startY = i; } else if (strcmpignorecase(key[i], "NAME") == 0) { name = i; } i++; } line = strtok_r(NULL, "\n", &savePtr); } loadInventoryItems(); return line; }
/** * @brief Conditions for moving items between containers. * @param[in] inv The inventory to move in. * @param[in] from Source container. * @param[in] fItem The item to be moved. * @param[in] to Destination container. * @param[in] tx X coordinate in destination container. * @param[in] ty Y coordinate in destination container. * @param[in,out] TU pointer to entity available TU at this moment * or @c nullptr if TU doesn't matter (outside battlescape) * @param[out] uponItem The item fItem is evetually dropped upon * @return IA_NOTIME when not enough TU. * @return IA_NONE if no action possible. * @return IA_NORELOAD if you cannot reload a weapon. * @return IA_RELOAD_SWAP in case of exchange of ammo in a weapon. * @return IA_RELOAD when reloading. * @return IA_ARMOUR when placing an armour on the actor. * @return IA_MOVE when just moving an item. */ inventory_action_t InventoryInterface::moveInInventory (Inventory* const inv, const invDef_t* from, Item* fItem, const invDef_t* to, int tx, int ty, int* TU, Item** uponItem) { assert(to); assert(from); if (uponItem) *uponItem = nullptr; if (from == to && fItem->getX() == tx && fItem->getY() == ty) return IA_NONE; int time = from->out + to->in; if (from == to) { if (from->isFloorDef()) time = 0; else time /= 2; } if (TU && *TU < time) return IA_NOTIME; assert(inv); int checkedTo = INV_DOES_NOT_FIT; /* Special case for moving an item within the same container. */ if (from == to) { /* Do nothing if we move inside a scroll container. */ if (from->scroll) return IA_NONE; const Container& cont = inv->getContainer(from->id); Item* item = nullptr; while ((item = cont.getNextItem(item))) { if (item != fItem) continue; if (item->getAmount() <= 1) continue; checkedTo = inv->canHoldItem(to, item->def(), tx, ty, fItem); if (!(checkedTo & INV_FITS)) return IA_NONE; item->setX(tx); item->setY(ty); if (uponItem) *uponItem = item; return IA_MOVE; } } /* If weapon is twohanded and is moved from hand to hand do nothing. */ /* Twohanded weapon are only in CID_RIGHT. */ if (fItem->def()->fireTwoHanded && to->isLeftDef() && from->isRightDef()) { return IA_NONE; } /* If non-armour moved to an armour slot then abort. * Same for non extension items when moved to an extension slot. */ if ((to->armour && !fItem->isArmour()) || (to->implant && !fItem->def()->implant) || (to->headgear && !fItem->def()->headgear)) { return IA_NONE; } /* Check if the target is a blocked inv-armour and source!=dest. */ if (to->single) checkedTo = inv->canHoldItem(to, fItem->def(), 0, 0, fItem); else { if (tx == NONE || ty == NONE) inv->findSpace(to, fItem, &tx, &ty, fItem); /* still no valid location found */ if (tx == NONE || ty == NONE) return IA_NONE; checkedTo = inv->canHoldItem(to, fItem->def(), tx, ty, fItem); } Item* ic; bool alreadyRemovedSource = false; if (to->armour && from != to && !checkedTo) { /* Store x/y origin coordinates of removed (source) item. * When we re-add it we can use this. */ const int cacheFromX = fItem->getX(); const int cacheFromY = fItem->getY(); /* Check if destination/blocking item is the same as source/from item. * In that case the move is not needed -> abort. */ Item* icTo = inv->getItemAtPos(to, tx, ty); if (fItem->def() == icTo->def()) return IA_NONE; /* Actually remove the ammo from the 'from' container. */ if (!removeFromInventory(inv, from, fItem)) return IA_NONE; else /* Removal successful - store this info. */ alreadyRemovedSource = true; Item cacheItem2 = this->cacheItem; /* Save/cache (source) item. The cacheItem is modified in MoveInInventory. */ /* Move the destination item to the source. */ moveInInventory(inv, to, icTo, from, cacheFromX, cacheFromY, TU, uponItem); /* Reset the cached item (source) (It'll be move to container emptied by destination item later.) */ this->cacheItem = cacheItem2; checkedTo = inv->canHoldItem(to, this->cacheItem.def(), 0, 0, fItem); } else if (!checkedTo) { /* Get the target-invlist (e.g. a weapon). We don't need to check for * scroll because checkedTo is always true here. */ ic = inv->getItemAtPos(to, tx, ty); if (ic && !to->isEquipDef() && fItem->def()->isLoadableInWeapon(ic->def())) { /* A target-item was found and the dragged item (implicitly ammo) * can be loaded in it (implicitly weapon). */ if (ic->getAmmoLeft() >= ic->def()->ammo && ic->ammoDef() == fItem->def()) { /* Weapon already fully loaded with the same ammunition -> abort */ return IA_NORELOAD; } time += ic->def()->getReloadTime(); if (!TU || *TU >= time) { if (TU) *TU -= time; if (ic->getAmmoLeft() >= ic->def()->ammo) { /* exchange ammo */ const Item item(ic->ammoDef()); /* Put current ammo in place of the new ammo unless floor - there can be more than 1 item */ const int cacheFromX = from->isFloorDef() ? NONE : fItem->getX(); const int cacheFromY = from->isFloorDef() ? NONE : fItem->getY(); /* Actually remove the ammo from the 'from' container. */ if (!removeFromInventory(inv, from, fItem)) return IA_NONE; /* Add the currently used ammo in place of the new ammo in the "from" container. */ if (addToInventory(inv, &item, from, cacheFromX, cacheFromY, 1) == nullptr) Sys_Error("Could not reload the weapon - add to inventory failed (%s)", invName); ic->setAmmoDef(this->cacheItem.def()); if (uponItem) *uponItem = ic; return IA_RELOAD_SWAP; } else { /* Actually remove the ammo from the 'from' container. */ if (!removeFromInventory(inv, from, fItem)) return IA_NONE; ic->setAmmoDef(this->cacheItem.def()); /* loose ammo of type ic->m saved on server side */ ic->setAmmoLeft(ic->def()->ammo); if (uponItem) *uponItem = ic; return IA_RELOAD; } } /* Not enough time -> abort. */ return IA_NOTIME; } /* temp container like CID_EQUIP and CID_FLOOR */ if (ic && to->temp) { /* We are moving to a blocked location container but it's the base-equipment floor or a battlescape floor. * We add the item anyway but it'll not be displayed (yet) * This is then used in addToInventory below.*/ /** @todo change the other code to browse through these things. */ inv->findSpace(to, fItem, &tx, &ty, fItem); if (tx == NONE || ty == NONE) { Com_DPrintf(DEBUG_SHARED, "MoveInInventory - item will be added non-visible (%s)\n", invName); } } else { /* Impossible move -> abort. */ return IA_NONE; } } /* twohanded exception - only CID_RIGHT is allowed for fireTwoHanded weapons */ if (fItem->def()->fireTwoHanded && to->isLeftDef()) to = &this->csi->ids[CID_RIGHT]; switch (checkedTo) { case INV_DOES_NOT_FIT: /* Impossible move - should be handled above, but add an abort just in case */ Com_Printf("MoveInInventory: Item doesn't fit into container."); return IA_NONE; case INV_FITS: /* Remove rotated tag */ fItem->rotated = false; break; case INV_FITS_ONLY_ROTATED: /* Set rotated tag */ fItem->rotated = true; break; case INV_FITS_BOTH: /* Leave rotated tag as-is */ break; } /* Actually remove the item from the 'from' container (if it wasn't already removed). */ if (!alreadyRemovedSource) if (!removeFromInventory(inv, from, fItem)) return IA_NONE; /* successful */ if (TU) *TU -= time; assert(this->cacheItem.def()); ic = addToInventory(inv, &this->cacheItem, to, tx, ty, 1); /* return data */ if (uponItem) { assert(ic); *uponItem = ic; } if (to->isArmourDef()) { assert(this->cacheItem.isArmour()); return IA_ARMOUR; } return IA_MOVE; }