#include #include "player.h" static void Inventory_save (FILE *, Inventory *); static void Inventory_load (FILE *, Inventory *); static void InvSlot_save (FILE *, InvSlot *); static void InvSlot_load (FILE *, InvSlot *); /* Player_save * Saves a player file to the specified path. Returns 0 on success, non-zero on * failure. */ int Player_save (Player *player, const char *path) { FILE *file = fopen(path, "w"); if (file == NULL) { return 1; } fprintf ( file, "%i\n" "%16.4lf %16.4lf %16.4lf\n" "%16.4lf %16.4lf\n" "%i %i %i\n" "%i\n\n", 0, player->pos.x, player->pos.y, player->pos.z, player->hRot, player->vRot, player->health, player->hunger, player->breath, player->xp); Inventory_save(file, &player->inventory); fclose(file); return 0; } /* Player_save * Loads a player from the specified file. Returns 0 on success, non-zero on * failure. */ int Player_load (Player *player, const char *path) { FILE *file = fopen(path, "r"); if (file == NULL) { return 1; } int version; fscanf(file, "%i", &version); if (version != 0) { return 2; } int health, hunger, breath, xp; fscanf ( file, "%lf %lf %lf " "%lf %lf " "%i %i %i " "%i", &player->pos.x, &player->pos.y, &player->pos.z, &player->hRot, &player->vRot, &health, &hunger, &breath, &xp); player->health = health; player->hunger = hunger; player->breath = breath; player->xp = xp; Inventory_load(file, &player->inventory); fclose(file); return 0; } /* Inventory_transferIn * Transfers items from src int dest. This will transfer as many items as it * can. Returns true if all items were transferred, false if some items weren't. */ int Inventory_transferIn (Inventory *dest, InvSlot *src) { // Look for exact match in hotbar for (int i = 0; i < HOTBAR_SIZE; i ++) { if(dest->hotbar[i].blockid == src->blockid) { if (InvSlot_transfer(&dest->hotbar[i], src)) { return 1; } } } // Look for exact match in inventory for (int i = 0; i < INVENTORY_SIZE; i ++) { if(dest->slots[i].blockid == src->blockid) { if (InvSlot_transfer(&dest->slots[i], src)) { return 1; } } } // Look for empty slot in inventory for (int i = 0; i < HOTBAR_SIZE; i ++) { if(dest->hotbar[i].blockid == 0) { if (InvSlot_transfer(&dest->hotbar[i], src)) { return 1; } } } // Look for exact match in inventory for (int i = 0; i < INVENTORY_SIZE; i ++) { if(dest->slots[i].blockid == 0) { if (InvSlot_transfer(&dest->slots[i], src)) { return 1; } } } return 0; } /* Inventory_save * Saves inventory contents to the specified file. Only intended for use inside * of Player_save. */ static void Inventory_save (FILE *file, Inventory *inventory) { InvSlot_save(file, &inventory->offhand); for (int index = 0; index < HOTBAR_SIZE; index ++) { InvSlot_save(file, &inventory->hotbar[index]); } for (int index = 0; index < INVENTORY_SIZE; index ++) { InvSlot_save(file, &inventory->slots[index]); } for (int index = 0; index < ARMOR_SIZE; index ++) { InvSlot_save(file, &inventory->armor[index]); } fprintf(file, "%i\n", inventory->hotbarSelect); } /* Inventory_load * Loads inventory contents from the specified file. Only intended for use * inside of Player_load. */ static void Inventory_load (FILE *file, Inventory *inventory) { InvSlot_load(file, &inventory->offhand); for (int index = 0; index < HOTBAR_SIZE; index ++) { InvSlot_load(file, &inventory->hotbar[index]); } for (int index = 0; index < INVENTORY_SIZE; index ++) { InvSlot_load(file, &inventory->slots[index]); } for (int index = 0; index < ARMOR_SIZE; index ++) { InvSlot_load(file, &inventory->armor[index]); } fscanf(file, "%i\n", &inventory->hotbarSelect); } /* InvSlot_save * Saves inventory slot to the specified file. Only intended for use inside of * Inventory_save. */ static void InvSlot_save (FILE *file, InvSlot *invSlot) { fprintf (file, "%i %i %i\n", invSlot->blockid, invSlot->amount, invSlot->durability); } /* InvSlot_load * Loads inventory slot description into the specified slot. Only indented for * use inside of Inventory_load. */ static void InvSlot_load (FILE *file, InvSlot *invSlot) { int blockid, amount, durability; fscanf (file, "%i %i %i\n", &blockid, &amount, &durability); invSlot->blockid = blockid; invSlot->amount = amount; invSlot->durability = durability; } /* InvSlot_transfer * Transfers items from src int dest. This will transfer as many items as it * can. Returns true if all items were transferred, false if some items weren't. * * This function will overwrite data about the item, so only call this function * if you know that dest and src contain the same thing (or dest is empty). */ int InvSlot_transfer (InvSlot *dest, InvSlot *src) { int want = 64 - dest->amount; if (want > src->amount) { want = src->amount; } dest->amount += want; src->amount -= want; dest->blockid = src->blockid; dest->durability = src->durability; return src->amount == 0; } /* InvSlow_swap * Swaps the data in two inventory slots. This is used for inventory management. */ void InvSlot_swap (InvSlot *left, InvSlot *right) { InvSlot temp = *left; *left = *right; *right = temp; }