From 94d0c934ae1aaee69cc50c32836810729eaeca4a Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 21 Jan 2018 12:57:01 +0000 Subject: [PATCH] Objectives. --- common.mk | 1 + src/defs.h | 18 ++++ src/structs.h | 9 ++ src/world/objectives.c | 184 +++++++++++++++++++++++++++++++++++++++++ src/world/objectives.h | 27 ++++++ 5 files changed, 239 insertions(+) create mode 100644 src/world/objectives.c create mode 100644 src/world/objectives.h diff --git a/common.mk b/common.mk index 251db56..484a958 100644 --- a/common.mk +++ b/common.mk @@ -16,6 +16,7 @@ OBJS += hud.o OBJS += init.o input.o io.o OBJS += lookup.o OBJS += main.o map.o maths.o +OBJS += objectives.o OBJS += quadtree.o OBJS += text.o textures.o title.o triggers.o OBJS += util.o diff --git a/src/defs.h b/src/defs.h index e3088d9..9847b2d 100644 --- a/src/defs.h +++ b/src/defs.h @@ -74,6 +74,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAP_TILE_OUTSIDE 255 #define MAP_TILE_MAX 256 +#define ET_ENEMY 0 +#define ET_KEY 1 +#define ET_MIA 2 + +#define EF_NONE 0 +#define EF_HEART_CELL (2 << 0) + +enum +{ + ALIVE_ALIVE +}; + enum { CONTROL_LEFT, @@ -94,6 +106,12 @@ enum TA_CENTER }; +enum +{ + MS_PARTIAL, + MS_MISSING_HEART_CELL +}; + enum { MSG_STANDARD, diff --git a/src/structs.h b/src/structs.h index cd1bbee..3dd985a 100644 --- a/src/structs.h +++ b/src/structs.h @@ -75,10 +75,15 @@ typedef struct { } Delegate; struct Entity { + char name[MAX_NAME_LENGTH]; + int type; float x; float y; int w; int h; + int alive; + long flags; + Entity *next; }; struct Objective { @@ -167,6 +172,10 @@ struct Quadtree { typedef struct { Entity *bob; Map map; + Entity entityHead, *entityTail; + int allObjectivesComplete; + int currentStatus; Quadtree quadtree; + Objective objectiveHead, *objectiveTail; Trigger triggerHead, *triggerTail; } World; diff --git a/src/world/objectives.c b/src/world/objectives.c new file mode 100644 index 0000000..cbae88c --- /dev/null +++ b/src/world/objectives.c @@ -0,0 +1,184 @@ +/* +Copyright (C) 2018 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 "objectives.h" + +static int isMissingHeartCell(char *targetName); +static int countTargetsInWorld(char *targetName); + +static int missingHeartCell; +static int isReturnVisit; +static int isEliminateAllEnemies; + +void initObjectives(void) +{ + int totalTargets; + Objective *o; + + isReturnVisit = world.currentStatus == MS_PARTIAL || world.currentStatus == MS_MISSING_HEART_CELL; + missingHeartCell = world.currentStatus == MS_MISSING_HEART_CELL; + + for (o = world.objectiveHead.next ; o != NULL ; o = o->next) + { + totalTargets = countTargetsInWorld(o->targetName); + + if (strcmp(o->targetName, "ENEMY") == 0) + { + isEliminateAllEnemies = 1; + } + + if (o->totalValue == 0) + { + o->totalValue = totalTargets; + } + + if (o->targetValue == 0) + { + if (strcmp(o->targetName, "KEY") == 0) + { + o->targetValue = totalTargets; + } + else + { + o->targetValue = (int) (totalTargets * AUTO_THRESHOLD); + } + } + + if (o->required && isReturnVisit) + { + o->targetValue = o->totalValue; + o->required = 0; + } + } +} + +static int countTargetsInWorld(char *targetName) +{ + int num, countMIAs, countEnemies, countKeys; + Entity *e; + + num = 0; + countMIAs = strcmp(targetName, "MIA") == 0; + countEnemies = strcmp(targetName, "ENEMY") == 0; + countKeys = strcmp(targetName, "KEY") == 0; + + for (e = world.entityHead.next ; e != NULL ; e = e->next) + { + if (strcmp(targetName, e->name) == 0) + { + num++; + } + + if (countMIAs && e->type == ET_MIA) + { + num++; + } + + if (countEnemies && e->type == ET_ENEMY) + { + num++; + } + + if (countKeys && e->type == ET_KEY) + { + num++; + } + } + + return num; +} + +void updateObjective(char *targetName) +{ + Objective *o; + + if (missingHeartCell && !isMissingHeartCell(targetName)) + { + return; + } + + for (o = world.objectiveHead.next ; o != NULL ; o = o->next) + { + if (strcmp(o->targetName, targetName) == 0) + { + o->currentValue++; + + if (strcmp(o->targetName, "KEY") != 0) + { + if (o->currentValue == o->targetValue) + { + setGameplayMessage(MSG_OBJECTIVE, "%s - Objective Complete!", o->description); + } + else if (o->currentValue < o->targetValue) + { + if (strcmp(o->targetName, "ENEMY") != 0) + { + setGameplayMessage(MSG_PROGRESS, "%s - (%d / %d)", o->description, o->currentValue, o->targetValue); + } + else if (o->targetValue - o->currentValue < 10 || o->currentValue % 5 == 0) + { + setGameplayMessage(MSG_PROGRESS, "%s - (%d / %d)", o->description, o->currentValue, o->targetValue); + } + } + } + } + } + + world.allObjectivesComplete = 1; + + for (o = world.objectiveHead.next ; o != NULL ; o = o->next) + { + if (o->currentValue < o->targetValue) + { + if (o->required || isReturnVisit) + { + world.allObjectivesComplete = 0; + } + } + } + + if (world.allObjectivesComplete) + { + setGameplayMessage(MSG_OBJECTIVE, "Mission Complete!"); + } +} + +static int isMissingHeartCell(char *targetName) +{ + Entity *e; + + if (targetName == NULL || strcmp(targetName, "HEART_CELL") == 0) + { + return 0; + } + + for (e = world.entityHead.next ; e != NULL ; e = e->next) + { + if (e->alive == ALIVE_ALIVE) + { + if (e->flags & EF_HEART_CELL) + { + return 0; + } + } + } + + return 1; +} diff --git a/src/world/objectives.h b/src/world/objectives.h new file mode 100644 index 0000000..15b4a04 --- /dev/null +++ b/src/world/objectives.h @@ -0,0 +1,27 @@ +/* +Copyright (C) 2018 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 "../common.h" + +#define AUTO_THRESHOLD 0.75 + +extern void setGameplayMessage(int type, char *format, ...); + +extern World world;