Mercurial > molko
view src/core/inventory.c @ 87:ebbf35d90088
misc: fix several portability issues
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 11 Mar 2020 20:36:10 +0100 |
parents | 34e91215ec5a |
children | d3bc14c1e243 |
line wrap: on
line source
/* * inventory.c -- inventory of items * * Copyright (c) 2020 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <assert.h> #include <stddef.h> #include <string.h> #include "inventory.h" #include "item.h" static bool can_be_used(struct inventory_slot *slot, const struct item *item) { assert(item); /* Empty slot. */ if (!slot->item) return false; /* Not same object. */ if (strcmp(slot->item->name, item->name) != 0) return false; /* No space in this slot. */ if (slot->amount >= slot->item->stackable) return false; return true; } static struct inventory_slot * find(struct inventory *iv, const struct item *item) { assert(iv); assert(item); /* First pass: find an entry with the same item. */ for (unsigned int r = 0; r < INVENTORY_ROWS_MAX; ++r) for (unsigned int c = 0; c < INVENTORY_COLS_MAX; ++c) if (can_be_used(&iv->items[r][c], item)) return &iv->items[r][c]; /* Second pass: try to find an empty slot. */ for (unsigned int r = 0; r < INVENTORY_ROWS_MAX; ++r) for (unsigned int c = 0; c < INVENTORY_COLS_MAX; ++c) if (!iv->items[r][c].item) return &iv->items[r][c]; return NULL; } static unsigned provide(struct inventory_slot *slot, struct item *item, unsigned int amount) { assert(slot); unsigned int avail; /* The slot may be empty, make sure it contains this item. */ slot->item = item; /* * Example: * * The slot has already 10 items. * The slot item is stackble up to 64 items. * * When pushing: * * 80: 54 pushed, 26 left * 30: 30 pushed, 0 left. */ avail = slot->item->stackable - slot->amount; if (amount > avail) { slot->amount += avail; amount -= avail; } else { slot->amount += amount; amount = 0; } return amount; } unsigned int inventory_push(struct inventory *iv, struct item *item, unsigned int amount) { assert(iv); assert(item); while (amount) { struct inventory_slot *slot; if (!(slot = find(iv, item))) break; /* Add as much as we can in this slot. */ amount = provide(slot, item, amount); } return amount; } void inventory_clear(struct inventory *iv) { assert(iv); memset(iv, 0, sizeof (*iv)); }