/* Copyright (C) 2015-2019 Parallel Realities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "items.h" static void action(void); static Entity *getItemDef(char *name); static Entity defHead, *defTail; void loadItemDefs(void) { cJSON *root, *node; char *text; Entity *e; text = readFile("data/battle/items.json"); root = cJSON_Parse(text); memset(&defHead, 0, sizeof(Entity)); defTail = &defHead; for (node = root->child ; node != NULL ; node = node->next) { e = malloc(sizeof(Entity)); memset(e, 0, sizeof(Entity)); e->type = ET_ITEM; e->active = 1; STRNCPY(e->name, cJSON_GetObjectItem(node, "name")->valuestring, MAX_NAME_LENGTH); STRNCPY(e->defName, cJSON_GetObjectItem(node, "defName")->valuestring, MAX_NAME_LENGTH); e->texture = getAtlasImage(cJSON_GetObjectItem(node, "texture")->valuestring); e->health = e->maxHealth = FPS; e->flags = EF_NO_HEALTH_BAR; e->w = e->texture->rect.w; e->h = e->texture->rect.h; defTail->next = e; defTail = e; } cJSON_Delete(root); free(text); } Entity *spawnItem(char *name) { Entity *e, *def, *item; def = NULL; item = spawnEntity(); if (strcmp(name, "RANDOM")) { def = getItemDef(name); } else { for (e = defHead.next ; e != NULL ; e = e->next) { if (!def || rand() % 2) { def = e; } } } memcpy(item, def, sizeof(Entity)); item->next = NULL; item->action = action; return item; } void addRandomItem(int x, int y) { Entity *item; item = spawnItem("RANDOM"); item->x = x; item->y = y; item->speed = 1; item->dx = rand() % 200 - rand() % 200; item->dy = rand() % 200 - rand() % 200; item->dx *= 0.01; item->dy *= 0.01; item->action = action; } static Entity *getItemDef(char *defName) { Entity *e; for (e = defHead.next ; e != NULL ; e = e->next) { if (strcmp(e->defName, defName) == 0) { return e; } } printf("Error: no such item '%s'\n", defName); exit(1); } static void action(void) { Entity *e, **candidates; int i; candidates = getAllEntsInRadius(self->x, self->y, MAX(self->w, self->h), self); for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) { if (e->alive == ALIVE_ALIVE && (e->flags & EF_COLLECTS_ITEMS) && collision(self->x - (self->w / 2), self->y - (self->h / 2), self->w, self->h, e->x - (e->w / 2), e->y - (e->h / 2), e->w, e->h)) { self->health = 0; playBattleSound(SND_GET_ITEM, self->x, self->y); updateObjective(self->name, TT_ITEM); if (e == player) { addHudMessage(colors.white, _("Picked up %s"), self->name); battle.stats[STAT_ITEMS_COLLECTED_PLAYER]++; } else { battle.stats[STAT_ITEMS_COLLECTED]++; } self->action = NULL; } } } void loadItems(cJSON *node) { Entity *e; char *name, *groupName, *type; int i, scatter, number, active, addFlags; long flags; float x, y; flags = -1; scatter = 1; if (node) { node = node->child; while (node) { type = cJSON_GetObjectItem(node, "type")->valuestring; x = (cJSON_GetObjectItem(node, "x")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_WIDTH; y = (cJSON_GetObjectItem(node, "y")->valuedouble / BATTLE_AREA_CELLS) * BATTLE_AREA_HEIGHT; name = NULL; groupName = NULL; name = getJSONValueStr(node, "name", NULL); groupName = getJSONValueStr(node, "groupName", NULL); number = getJSONValue(node, "number", 1); scatter = getJSONValue(node, "scatter", 1); active = getJSONValue(node, "active", 1); if (cJSON_GetObjectItem(node, "flags")) { flags = flagsToLong(cJSON_GetObjectItem(node, "flags")->valuestring, &addFlags); } for (i = 0 ; i < number ; i++) { e = spawnItem(type); if (name) { STRNCPY(e->name, name, MAX_NAME_LENGTH); } if (groupName) { STRNCPY(e->groupName, groupName, MAX_NAME_LENGTH); } if (flags != -1) { if (addFlags) { e->flags |= flags; } else { e->flags = flags; SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Flags for '%s' (%s) replaced", e->name, e->defName); } } e->x = x; e->y = y; e->active = active; if (scatter > 1) { e->x += (rand() % scatter) - (rand() % scatter); e->y += (rand() % scatter) - (rand() % scatter); } e->w = e->texture->rect.w; e->h = e->texture->rect.h; } node = node->next; } } } void destroyItemDefs(void) { Entity *e; while (defHead.next) { e = defHead.next; defHead.next = e->next; free(e); } }