Draw jumpgate portal in jumpgate.c. Use systemPower instead of ALIVE_SLEEPING to determine status.

This commit is contained in:
Steve 2016-03-08 14:28:11 +00:00
parent 5267b7b559
commit 7118c10648
9 changed files with 192 additions and 169 deletions

View File

@ -94,13 +94,13 @@ void doCapitalShip(void)
if (self->side == SIDE_ALLIES) if (self->side == SIDE_ALLIES)
{ {
battle.stats[STAT_CAPITAL_SHIPS_LOST]++; battle.stats[STAT_CAPITAL_SHIPS_LOST]++;
runScriptFunction("CAPITAL_SHIPS_LOST %d", battle.stats[STAT_CAPITAL_SHIPS_LOST]); runScriptFunction("CAPITAL_SHIPS_LOST %d", battle.stats[STAT_CAPITAL_SHIPS_LOST]);
} }
else else
{ {
battle.stats[STAT_CAPITAL_SHIPS_DESTROYED]++; battle.stats[STAT_CAPITAL_SHIPS_DESTROYED]++;
runScriptFunction("CAPITAL_SHIPS_DESTROYED %d", battle.stats[STAT_CAPITAL_SHIPS_DESTROYED]); runScriptFunction("CAPITAL_SHIPS_DESTROYED %d", battle.stats[STAT_CAPITAL_SHIPS_DESTROYED]);
} }
} }
@ -356,7 +356,7 @@ static void loadCapitalShipDef(char *filename)
e->type = ET_CAPITAL_SHIP; e->type = ET_CAPITAL_SHIP;
e->active = 1; e->active = 1;
STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH); STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
STRNCPY(e->defName, e->name, MAX_NAME_LENGTH); STRNCPY(e->defName, e->name, MAX_NAME_LENGTH);
e->shield = e->maxShield = cJSON_GetObjectItem(root, "shield")->valueint; e->shield = e->maxShield = cJSON_GetObjectItem(root, "shield")->valueint;
@ -379,7 +379,7 @@ static void loadCapitalShipDef(char *filename)
cJSON_Delete(root); cJSON_Delete(root);
} }
free(text); free(text);
} }
@ -421,7 +421,7 @@ static void loadComponents(Entity *parent, cJSON *components)
e->aiFlags = flagsToLong(cJSON_GetObjectItem(component, "aiFlags")->valuestring, NULL); e->aiFlags = flagsToLong(cJSON_GetObjectItem(component, "aiFlags")->valuestring, NULL);
} }
e->systemPower = 100; e->systemPower = MAX_SYSTEM_POWER;
e->die = componentDie; e->die = componentDie;
@ -475,7 +475,7 @@ static void loadGuns(Entity *parent, cJSON *guns)
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
e->systemPower = 100; e->systemPower = MAX_SYSTEM_POWER;
e->action = gunThink; e->action = gunThink;
e->die = gunDie; e->die = gunDie;
@ -518,7 +518,7 @@ static void loadEngines(Entity *parent, cJSON *engines)
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
e->systemPower = 100; e->systemPower = MAX_SYSTEM_POWER;
e->action = engineThink; e->action = engineThink;
e->die = engineDie; e->die = engineDie;

View File

@ -31,8 +31,6 @@ static int drawComparator(const void *a, const void *b);
static void notifyNewArrivals(void); static void notifyNewArrivals(void);
static int isCapitalShipComponent(Entity *e); static int isCapitalShipComponent(Entity *e);
static SDL_Texture *jumpPortal;
static float jumpPortAngle;
static Entity deadHead; static Entity deadHead;
static Entity *deadTail; static Entity *deadTail;
static int disabledGlow; static int disabledGlow;
@ -41,14 +39,11 @@ static int disabledGlowDir;
void initEntities(void) void initEntities(void)
{ {
memset(&deadHead, 0, sizeof(Entity)); memset(&deadHead, 0, sizeof(Entity));
deadTail = &deadHead; deadTail = &deadHead;
disabledGlow = DISABLED_GLOW_MAX; disabledGlow = DISABLED_GLOW_MAX;
disabledGlowDir = -DISABLED_GLOW_SPEED; disabledGlowDir = -DISABLED_GLOW_SPEED;
jumpPortal = getTexture("gfx/entities/portal.png");
jumpPortAngle = 0;
} }
Entity *spawnEntity(void) Entity *spawnEntity(void)
@ -57,10 +52,10 @@ Entity *spawnEntity(void)
memset(e, 0, sizeof(Entity)); memset(e, 0, sizeof(Entity));
e->id = battle.entId++; e->id = battle.entId++;
e->active = 1; e->active = 1;
battle.entityTail->next = e; battle.entityTail->next = e;
battle.entityTail = e; battle.entityTail = e;
return e; return e;
} }
@ -69,33 +64,33 @@ void doEntities(void)
int numAllies, numEnemies; int numAllies, numEnemies;
int numActiveAllies, numActiveEnemies; int numActiveAllies, numActiveEnemies;
Entity *e, *prev; Entity *e, *prev;
prev = &battle.entityHead; prev = &battle.entityHead;
numAllies = numEnemies = numActiveAllies = numActiveEnemies = 0; numAllies = numEnemies = numActiveAllies = numActiveEnemies = 0;
if (dev.playerImmortal) if (dev.playerImmortal)
{ {
player->health = player->maxHealth; player->health = player->maxHealth;
player->shield = player->maxShield; player->shield = player->maxShield;
} }
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{ {
removeFromQuadtree(e, &battle.quadtree); removeFromQuadtree(e, &battle.quadtree);
if (dev.allImmortal) if (dev.allImmortal)
{ {
e->health = e->maxHealth; e->health = e->maxHealth;
e->shield = e->maxShield; e->shield = e->maxShield;
} }
if (e->active) if (e->active)
{ {
self = e; self = e;
e->reload = MAX(e->reload - 1, 0); e->reload = MAX(e->reload - 1, 0);
if (e->shieldRechargeRate) if (e->shieldRechargeRate)
{ {
if (e->shield >= 0) if (e->shield >= 0)
@ -103,7 +98,7 @@ void doEntities(void)
if (--e->shieldRecharge <= 0) if (--e->shieldRecharge <= 0)
{ {
e->shield = MIN(e->shield + 1, e->maxShield); e->shield = MIN(e->shield + 1, e->maxShield);
e->shieldRecharge = e->shieldRechargeRate; e->shieldRecharge = e->shieldRechargeRate;
} }
} }
@ -112,34 +107,34 @@ void doEntities(void)
e->shield++; e->shield++;
} }
} }
e->armourHit = MAX(e->armourHit - 25, 0); e->armourHit = MAX(e->armourHit - 25, 0);
e->shieldHit = MAX(e->shieldHit - 5, 0); e->shieldHit = MAX(e->shieldHit - 5, 0);
e->systemHit = MAX(e->systemHit - 25, 0); e->systemHit = MAX(e->systemHit - 25, 0);
e->aiDamageTimer = MAX(e->aiDamageTimer - 1, 0); e->aiDamageTimer = MAX(e->aiDamageTimer - 1, 0);
if (!e->aiDamageTimer) if (!e->aiDamageTimer)
{ {
e->aiDamagePerSec = 0; e->aiDamagePerSec = 0;
e->aiFlags &= ~AIF_EVADE; e->aiFlags &= ~AIF_EVADE;
} }
switch (e->type) switch (e->type)
{ {
case ET_FIGHTER: case ET_FIGHTER:
doFighter(); doFighter();
break; break;
case ET_CAPITAL_SHIP: case ET_CAPITAL_SHIP:
doCapitalShip(); doCapitalShip();
break; break;
default: default:
doEntity(); doEntity();
break; break;
} }
if (e->alive == ALIVE_ALIVE || e->alive == ALIVE_DYING || e->alive == ALIVE_SLEEPING) if (e->alive == ALIVE_ALIVE || e->alive == ALIVE_DYING)
{ {
if (e->action != NULL) if (e->action != NULL)
{ {
@ -147,26 +142,26 @@ void doEntities(void)
{ {
e->thinkTime = 2; e->thinkTime = 2;
} }
if (--e->thinkTime <= 0) if (--e->thinkTime <= 0)
{ {
e->thinkTime = 0; e->thinkTime = 0;
e->action(); e->action();
} }
} }
doRope(e); doRope(e);
restrictToBattleArea(e); restrictToBattleArea(e);
if (!e->speed) if (!e->speed)
{ {
e->dx = e->dy = 0; e->dx = e->dy = 0;
} }
e->x += e->dx; e->x += e->dx;
e->y += e->dy; e->y += e->dy;
if (!isCapitalShipComponent(e)) if (!isCapitalShipComponent(e))
{ {
addToQuadtree(e, &battle.quadtree); addToQuadtree(e, &battle.quadtree);
@ -178,38 +173,38 @@ void doEntities(void)
{ {
battle.entityTail = prev; battle.entityTail = prev;
} }
if (e == battle.missionTarget) if (e == battle.missionTarget)
{ {
battle.missionTarget = NULL; battle.missionTarget = NULL;
} }
if (e == player) if (e == player)
{ {
player = NULL; player = NULL;
battle.playerSelect = battle.isEpic; battle.playerSelect = battle.isEpic;
} }
cutRope(e); cutRope(e);
prev->next = e->next; prev->next = e->next;
/* move to dead list */ /* move to dead list */
e->next = NULL; e->next = NULL;
deadTail->next = e; deadTail->next = e;
deadTail = e; deadTail = e;
e = prev; e = prev;
} }
} }
if (e->type == ET_FIGHTER || e->type == ET_CAPITAL_SHIP) if (e->type == ET_FIGHTER || e->type == ET_CAPITAL_SHIP)
{ {
if (e->side == SIDE_ALLIES) if (e->side == SIDE_ALLIES)
{ {
numAllies++; numAllies++;
if (e->health > 0 && e->active) if (e->health > 0 && e->active)
{ {
numActiveAllies++; numActiveAllies++;
@ -218,37 +213,37 @@ void doEntities(void)
else else
{ {
numEnemies++; numEnemies++;
if (e->health > 0 && e->active) if (e->health > 0 && e->active)
{ {
numActiveEnemies++; numActiveEnemies++;
} }
} }
} }
prev = e; prev = e;
} }
battle.numAllies = (battle.isEpic) ? numAllies : numActiveAllies; battle.numAllies = (battle.isEpic) ? numAllies : numActiveAllies;
battle.numEnemies = (battle.isEpic) ? numEnemies : numActiveEnemies; battle.numEnemies = (battle.isEpic) ? numEnemies : numActiveEnemies;
if (battle.isEpic && battle.stats[STAT_TIME] % FPS == 0) if (battle.isEpic && battle.stats[STAT_TIME] % FPS == 0)
{ {
if (numAllies > battle.epicFighterLimit) if (numAllies > battle.epicFighterLimit)
{ {
activateEpicFighters(battle.epicFighterLimit - numActiveAllies, SIDE_ALLIES); activateEpicFighters(battle.epicFighterLimit - numActiveAllies, SIDE_ALLIES);
} }
if (numEnemies > battle.epicFighterLimit) if (numEnemies > battle.epicFighterLimit)
{ {
activateEpicFighters(battle.epicFighterLimit - numActiveEnemies, SIDE_NONE); activateEpicFighters(battle.epicFighterLimit - numActiveEnemies, SIDE_NONE);
} }
} }
alignComponents(); alignComponents();
disabledGlow = MAX(DISABLED_GLOW_MIN, MIN(disabledGlow + disabledGlowDir, DISABLED_GLOW_MAX)); disabledGlow = MAX(DISABLED_GLOW_MIN, MIN(disabledGlow + disabledGlowDir, DISABLED_GLOW_MAX));
if (disabledGlow <= DISABLED_GLOW_MIN) if (disabledGlow <= DISABLED_GLOW_MIN)
{ {
disabledGlowDir = DISABLED_GLOW_SPEED; disabledGlowDir = DISABLED_GLOW_SPEED;
@ -257,39 +252,33 @@ void doEntities(void)
{ {
disabledGlowDir = -DISABLED_GLOW_SPEED; disabledGlowDir = -DISABLED_GLOW_SPEED;
} }
jumpPortAngle += 0.5;
if (jumpPortAngle >= 360)
{
jumpPortAngle -= 360;
}
} }
static void restrictToBattleArea(Entity *e) static void restrictToBattleArea(Entity *e)
{ {
float force; float force;
if (e->x <= BATTLE_AREA_EDGE) if (e->x <= BATTLE_AREA_EDGE)
{ {
force = BATTLE_AREA_EDGE - e->x; force = BATTLE_AREA_EDGE - e->x;
e->dx += force * 0.001; e->dx += force * 0.001;
e->dx *= 0.95; e->dx *= 0.95;
} }
if (e->y <= BATTLE_AREA_EDGE) if (e->y <= BATTLE_AREA_EDGE)
{ {
force = BATTLE_AREA_EDGE - e->y; force = BATTLE_AREA_EDGE - e->y;
e->dy += force * 0.001; e->dy += force * 0.001;
e->dy *= 0.95; e->dy *= 0.95;
} }
if (e->x >= BATTLE_AREA_WIDTH - BATTLE_AREA_EDGE) if (e->x >= BATTLE_AREA_WIDTH - BATTLE_AREA_EDGE)
{ {
force = e->x - (BATTLE_AREA_WIDTH - BATTLE_AREA_EDGE); force = e->x - (BATTLE_AREA_WIDTH - BATTLE_AREA_EDGE);
e->dx -= force * 0.001; e->dx -= force * 0.001;
e->dx *= 0.95; e->dx *= 0.95;
} }
if (e->y >= BATTLE_AREA_HEIGHT - BATTLE_AREA_EDGE) if (e->y >= BATTLE_AREA_HEIGHT - BATTLE_AREA_EDGE)
{ {
force = e->y - (BATTLE_AREA_HEIGHT - BATTLE_AREA_EDGE); force = e->y - (BATTLE_AREA_HEIGHT - BATTLE_AREA_EDGE);
@ -307,7 +296,7 @@ static void doEntity(void)
self->health = 0; self->health = 0;
self->alive = ALIVE_DYING; self->alive = ALIVE_DYING;
self->die(); self->die();
if (self == battle.missionTarget) if (self == battle.missionTarget)
{ {
battle.missionTarget = NULL; battle.missionTarget = NULL;
@ -332,28 +321,28 @@ static void alignComponents(void)
Entity *e; Entity *e;
float x, y; float x, y;
float c, s; float c, s;
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{ {
if (isCapitalShipComponent(e)) if (isCapitalShipComponent(e))
{ {
s = sin(TO_RAIDANS(e->owner->angle)); s = sin(TO_RAIDANS(e->owner->angle));
c = cos(TO_RAIDANS(e->owner->angle)); c = cos(TO_RAIDANS(e->owner->angle));
x = (e->offsetX * c) - (e->offsetY * s); x = (e->offsetX * c) - (e->offsetY * s);
y = (e->offsetX * s) + (e->offsetY * c); y = (e->offsetX * s) + (e->offsetY * c);
x += e->owner->x; x += e->owner->x;
y += e->owner->y; y += e->owner->y;
e->x = x; e->x = x;
e->y = y; e->y = y;
if (e->flags & EF_STATIC) if (e->flags & EF_STATIC)
{ {
e->angle = e->owner->angle; e->angle = e->owner->angle;
} }
addToQuadtree(e, &battle.quadtree); addToQuadtree(e, &battle.quadtree);
} }
} }
@ -368,85 +357,86 @@ void drawEntities(void)
{ {
Entity *e, **candidates; Entity *e, **candidates;
int i; int i;
candidates = getAllEntsWithin(battle.camera.x, battle.camera.y, SCREEN_WIDTH, SCREEN_HEIGHT, NULL); candidates = getAllEntsWithin(battle.camera.x, battle.camera.y, SCREEN_WIDTH, SCREEN_HEIGHT, NULL);
/* count number of candidates for use with qsort */ /* count number of candidates for use with qsort */
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) {} for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) {}
qsort(candidates, i, sizeof(Entity*), drawComparator); qsort(candidates, i, sizeof(Entity*), drawComparator);
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
{ {
if (e->active) self = e;
if (e->draw)
{
e->draw();
}
else
{ {
drawEntity(e); drawEntity(e);
} }
drawTargetRects(e); drawTargetRects(e);
drawRope(e); drawRope(e);
} }
} }
static void drawEntity(Entity *e) static void drawEntity(Entity *e)
{ {
if (e->type == ET_JUMPGATE && e->alive == ALIVE_ALIVE)
{
blitRotated(jumpPortal, e->x - battle.camera.x, e->y - battle.camera.y, jumpPortAngle);
}
SDL_SetTextureColorMod(e->texture, 255, 255, 255); SDL_SetTextureColorMod(e->texture, 255, 255, 255);
if (e->armourHit > 0) if (e->armourHit > 0)
{ {
SDL_SetTextureColorMod(e->texture, 255, 255 - e->armourHit, 255 - e->armourHit); SDL_SetTextureColorMod(e->texture, 255, 255 - e->armourHit, 255 - e->armourHit);
} }
if (e->systemHit > 0) if (e->systemHit > 0)
{ {
SDL_SetTextureColorMod(e->texture, 255 - e->systemHit, 255, 255); SDL_SetTextureColorMod(e->texture, 255 - e->systemHit, 255, 255);
} }
if (e->flags & EF_DISABLED) if (e->flags & EF_DISABLED)
{ {
SDL_SetTextureColorMod(e->texture, disabledGlow, disabledGlow, 255); SDL_SetTextureColorMod(e->texture, disabledGlow, disabledGlow, 255);
} }
blitRotated(e->texture, e->x - battle.camera.x, e->y - battle.camera.y, e->angle); blitRotated(e->texture, e->x - battle.camera.x, e->y - battle.camera.y, e->angle);
if (e->shieldHit > 0) if (e->shieldHit > 0)
{ {
drawShieldHitEffect(e); drawShieldHitEffect(e);
} }
SDL_SetTextureColorMod(e->texture, 255, 255, 255); SDL_SetTextureColorMod(e->texture, 255, 255, 255);
} }
static void drawTargetRects(Entity *e) static void drawTargetRects(Entity *e)
{ {
SDL_Rect r; SDL_Rect r;
int size = MAX(e->w, e->h) + 16; int size = MAX(e->w, e->h) + 16;
if (player != NULL && e == player->target) if (player != NULL && e == player->target)
{ {
r.x = e->x - (size / 2) - battle.camera.x; r.x = e->x - (size / 2) - battle.camera.x;
r.y = e->y - (size / 2) - battle.camera.y; r.y = e->y - (size / 2) - battle.camera.y;
r.w = size; r.w = size;
r.h = size; r.h = size;
SDL_SetRenderDrawColor(app.renderer, 255, 0, 0, 255); SDL_SetRenderDrawColor(app.renderer, 255, 0, 0, 255);
SDL_RenderDrawRect(app.renderer, &r); SDL_RenderDrawRect(app.renderer, &r);
} }
if ((e == battle.missionTarget || e->flags & EF_MISSION_TARGET) && (e->flags & EF_NO_MT_BOX) == 0) if ((e == battle.missionTarget || e->flags & EF_MISSION_TARGET) && (e->flags & EF_NO_MT_BOX) == 0)
{ {
r.x = e->x - (size / 2) - battle.camera.x - 4; r.x = e->x - (size / 2) - battle.camera.x - 4;
r.y = e->y - (size / 2) - battle.camera.y - 4; r.y = e->y - (size / 2) - battle.camera.y - 4;
r.w = size + 8; r.w = size + 8;
r.h = size + 8; r.h = size + 8;
SDL_SetRenderDrawColor(app.renderer, 0, 255, 0, 255); SDL_SetRenderDrawColor(app.renderer, 0, 255, 0, 255);
SDL_RenderDrawRect(app.renderer, &r); SDL_RenderDrawRect(app.renderer, &r);
} }
@ -456,9 +446,9 @@ void activateEntities(char *names)
{ {
Entity *e; Entity *e;
char *name; char *name;
name = strtok(names, ";"); name = strtok(names, ";");
while (name) while (name)
{ {
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
@ -466,17 +456,17 @@ void activateEntities(char *names)
if (strcmp(e->name, name) == 0) if (strcmp(e->name, name) == 0)
{ {
e->active = 1; e->active = 1;
if (e->type == ET_CAPITAL_SHIP) if (e->type == ET_CAPITAL_SHIP)
{ {
updateCapitalShipComponentProperties(e); updateCapitalShipComponentProperties(e);
} }
} }
} }
name = strtok(NULL, ";"); name = strtok(NULL, ";");
} }
notifyNewArrivals(); notifyNewArrivals();
} }
@ -484,9 +474,9 @@ void activateEntityGroups(char *groupNames)
{ {
Entity *e; Entity *e;
char *groupName; char *groupName;
groupName = strtok(groupNames, ";"); groupName = strtok(groupNames, ";");
while (groupName) while (groupName)
{ {
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
@ -494,23 +484,28 @@ void activateEntityGroups(char *groupNames)
if (strcmp(e->groupName, groupName) == 0) if (strcmp(e->groupName, groupName) == 0)
{ {
e->active = 1; e->active = 1;
if (e->type == ET_CAPITAL_SHIP)
{
updateCapitalShipComponentProperties(e);
}
} }
} }
groupName = strtok(NULL, ";"); groupName = strtok(NULL, ";");
} }
notifyNewArrivals(); notifyNewArrivals();
} }
/* /*
* Some craft, such as capital ships, might be performing a long action and won't notice new craft arrive for well over 30 seconds. * Some craft, such as capital ships, might be performing a long action and won't notice new craft arrive for well over 30 seconds.
* We'll knock the times down to a max of 1 second, so they can react faster. * We'll knock the times down to a max of 1 second, so they can react faster.
*/ */
static void notifyNewArrivals(void) static void notifyNewArrivals(void)
{ {
Entity *e; Entity *e;
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{ {
if (e->active && (e->type == ET_FIGHTER || e->type == ET_CAPITAL_SHIP)) if (e->active && (e->type == ET_FIGHTER || e->type == ET_CAPITAL_SHIP))
@ -523,7 +518,7 @@ static void notifyNewArrivals(void)
static void activateEpicFighters(int n, int side) static void activateEpicFighters(int n, int side)
{ {
Entity *e; Entity *e;
if (n > 0) if (n > 0)
{ {
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
@ -531,7 +526,7 @@ static void activateEpicFighters(int n, int side)
if (!e->active && e->type == ET_FIGHTER && !(e->flags & EF_NO_EPIC) && ((side == SIDE_ALLIES && e->side == SIDE_ALLIES) || (side != SIDE_ALLIES && e->side != SIDE_ALLIES))) if (!e->active && e->type == ET_FIGHTER && !(e->flags & EF_NO_EPIC) && ((side == SIDE_ALLIES && e->side == SIDE_ALLIES) || (side != SIDE_ALLIES && e->side != SIDE_ALLIES)))
{ {
e->active = 1; e->active = 1;
if (--n <= 0) if (--n <= 0)
{ {
return; return;
@ -544,7 +539,7 @@ static void activateEpicFighters(int n, int side)
void countNumEnemies(void) void countNumEnemies(void)
{ {
Entity *e; Entity *e;
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{ {
if (e->side != SIDE_ALLIES && e->type == ET_FIGHTER) if (e->side != SIDE_ALLIES && e->type == ET_FIGHTER)
@ -552,14 +547,14 @@ void countNumEnemies(void)
battle.numInitialEnemies++; battle.numInitialEnemies++;
} }
} }
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "battle.numInitialEnemies=%d", battle.numInitialEnemies); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "battle.numInitialEnemies=%d", battle.numInitialEnemies);
} }
void addAllEntsToQuadtree(void) void addAllEntsToQuadtree(void)
{ {
Entity *e; Entity *e;
for (e = battle.entityHead.next ; e != NULL ; e = e->next) for (e = battle.entityHead.next ; e != NULL ; e = e->next)
{ {
addToQuadtree(e, &battle.quadtree); addToQuadtree(e, &battle.quadtree);
@ -570,20 +565,20 @@ static int drawComparator(const void *a, const void *b)
{ {
Entity *e1 = *((Entity**)a); Entity *e1 = *((Entity**)a);
Entity *e2 = *((Entity**)b); Entity *e2 = *((Entity**)b);
return e2->type - e1->type; return e2->type - e1->type;
} }
void destroyEntities(void) void destroyEntities(void)
{ {
Entity *e; Entity *e;
while (deadHead.next) while (deadHead.next)
{ {
e = deadHead.next; e = deadHead.next;
deadHead.next = e->next; deadHead.next = e->next;
free(e); free(e);
} }
deadTail = &deadHead; deadTail = &deadHead;
} }

View File

@ -660,7 +660,7 @@ static void loadFighterDef(char *filename)
e->type = ET_FIGHTER; e->type = ET_FIGHTER;
e->active = 1; e->active = 1;
STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH); STRNCPY(e->name, cJSON_GetObjectItem(root, "name")->valuestring, MAX_NAME_LENGTH);
STRNCPY(e->defName, e->name, MAX_NAME_LENGTH); STRNCPY(e->defName, e->name, MAX_NAME_LENGTH);
e->health = e->maxHealth = cJSON_GetObjectItem(root, "health")->valueint; e->health = e->maxHealth = cJSON_GetObjectItem(root, "health")->valueint;
@ -715,12 +715,11 @@ static void loadFighterDef(char *filename)
e->separationRadius = MAX(e->w, e->h) * 3; e->separationRadius = MAX(e->w, e->h) * 3;
/* all craft default to 100 system power */ e->systemPower = MAX_SYSTEM_POWER;
e->systemPower = 100;
cJSON_Delete(root); cJSON_Delete(root);
} }
free(text); free(text);
} }

View File

@ -21,55 +21,75 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "jumpgate.h" #include "jumpgate.h"
static void think(void); static void think(void);
static void draw(void);
static void handleFleeingEntities(void); static void handleFleeingEntities(void);
static void addEscapeEffect(Entity *ent); static void addEscapeEffect(Entity *ent);
static SDL_Texture *portal;
static float portalAngle;
Entity *spawnJumpgate(void) Entity *spawnJumpgate(void)
{ {
Entity *jumpgate = spawnEntity(); Entity *jumpgate = spawnEntity();
jumpgate->type = ET_JUMPGATE; jumpgate->type = ET_JUMPGATE;
jumpgate->health = jumpgate->maxHealth = FPS; jumpgate->health = jumpgate->maxHealth = FPS;
jumpgate->texture = getTexture("gfx/entities/jumpgate.png"); jumpgate->texture = getTexture("gfx/entities/jumpgate.png");
jumpgate->action = think; jumpgate->action = think;
jumpgate->draw = draw;
jumpgate->flags |= EF_NO_MT_BOX; jumpgate->flags |= EF_NO_MT_BOX;
portal = getTexture("gfx/entities/portal.png");
portalAngle = 0;
return jumpgate; return jumpgate;
} }
static void think(void) static void think(void)
{ {
self->thinkTime = 4; self->thinkTime = 4;
self->angle += 0.1; self->angle += 0.1;
if (self->angle >= 360) if (self->angle >= 360)
{ {
self->angle -= 360; self->angle -= 360;
} }
if (self->alive == ALIVE_ALIVE) if (self->systemPower)
{ {
handleFleeingEntities(); handleFleeingEntities();
} }
battle.jumpgate = self; if (!battle.jumpgate)
{
battle.jumpgate = self;
}
if (battle.jumpgate == self)
{
portalAngle += 0.5;
if (portalAngle >= 360)
{
portalAngle -= 360;
}
}
} }
static void handleFleeingEntities(void) static void handleFleeingEntities(void)
{ {
Entity *e, **candidates; Entity *e, **candidates;
int i; int i;
candidates = getAllEntsWithin(self->x - (self->w / 2), self->y - (self->h / 2), self->w, self->h, self); candidates = getAllEntsWithin(self->x - (self->w / 2), self->y - (self->h / 2), self->w, self->h, self);
for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i]) for (i = 0, e = candidates[i] ; e != NULL ; e = candidates[++i])
{ {
if (e->health > 0 && e->flags & EF_RETREATING && getDistance(self->x, self->y, e->x, e->y) <= 255) if (e->health > 0 && e->flags & EF_RETREATING && getDistance(self->x, self->y, e->x, e->y) <= 255)
{ {
e->alive = ALIVE_ESCAPED; e->alive = ALIVE_ESCAPED;
addEscapeEffect(e); addEscapeEffect(e);
playBattleSound(SND_JUMP, e->x, e->y); playBattleSound(SND_JUMP, e->x, e->y);
} }
} }
@ -79,29 +99,39 @@ static void addEscapeEffect(Entity *ent)
{ {
Effect *e; Effect *e;
int i, n, speed; int i, n, speed;
n = ent->w * ent->h; n = ent->w * ent->h;
for (i = 0 ; i < n ; i++) for (i = 0 ; i < n ; i++)
{ {
e = malloc(sizeof(Effect)); e = malloc(sizeof(Effect));
memset(e, 0, sizeof(Effect)); memset(e, 0, sizeof(Effect));
battle.effectTail->next = e; battle.effectTail->next = e;
battle.effectTail = e; battle.effectTail = e;
speed = 50 + rand() % 50; speed = 50 + rand() % 50;
e->type = EFFECT_POINT; e->type = EFFECT_POINT;
e->x = ent->x + (rand() % ent->w) - (rand() % ent->w); e->x = ent->x + (rand() % ent->w) - (rand() % ent->w);
e->y = ent->y + (rand() % ent->h) - (rand() % ent->w); e->y = ent->y + (rand() % ent->h) - (rand() % ent->w);
e->dx = self->x - e->x; e->dx = self->x - e->x;
e->dx /= speed; e->dx /= speed;
e->dy = self->y - e->y; e->dy = self->y - e->y;
e->dy /= speed; e->dy /= speed;
e->r = e->g = e->b = e->a = (rand() % 255); e->r = e->g = e->b = e->a = (rand() % 255);
e->health = speed; e->health = speed;
} }
} }
static void draw(void)
{
if (self->systemPower)
{
blitRotated(portal, self->x - battle.camera.x, self->y - battle.camera.y, portalAngle);
}
blitRotated(self->texture, self->x - battle.camera.x, self->y - battle.camera.y, self->angle);
}

View File

@ -25,6 +25,7 @@ extern Entity *spawnEntity(void);
extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore); extern Entity **getAllEntsWithin(int x, int y, int w, int h, Entity *ignore);
extern int getDistance(int x1, int y1, int x2, int y2); extern int getDistance(int x1, int y1, int x2, int y2);
extern void playBattleSound(int id, int x, int y); extern void playBattleSound(int id, int x, int y);
extern void blitRotated(SDL_Texture *texture, int x, int y, float angle);
extern Battle battle; extern Battle battle;
extern Entity *self; extern Entity *self;

View File

@ -30,42 +30,42 @@ void initScript(cJSON *scriptNode)
{ {
memset(&head, 0, sizeof(ScriptRunner)); memset(&head, 0, sizeof(ScriptRunner));
tail = &head; tail = &head;
scriptJSON = scriptNode; scriptJSON = scriptNode;
} }
void doScript(void) void doScript(void)
{ {
ScriptRunner *runner, *prev; ScriptRunner *runner, *prev;
prev = &head; prev = &head;
for (runner = head.next ; runner != NULL ; runner = runner->next) for (runner = head.next ; runner != NULL ; runner = runner->next)
{ {
runner->delay = MAX(0, runner->delay - 1); runner->delay = MAX(0, runner->delay - 1);
if (runner->waitForMessageBox) if (runner->waitForMessageBox)
{ {
runner->waitForMessageBox = showingMessageBoxes(); runner->waitForMessageBox = showingMessageBoxes();
} }
if (!runner->delay && !runner->waitForMessageBox) if (!runner->delay && !runner->waitForMessageBox)
{ {
executeNextLine(runner); executeNextLine(runner);
if (!runner->line) if (!runner->line)
{ {
if (runner == tail) if (runner == tail)
{ {
tail = prev; tail = prev;
} }
prev->next = runner->next; prev->next = runner->next;
free(runner); free(runner);
runner = prev; runner = prev;
} }
} }
prev = runner; prev = runner;
} }
} }
@ -85,26 +85,26 @@ void runScriptFunction(const char *format, ...)
va_start(args, format); va_start(args, format);
vsprintf(funcNameBuffer, format, args); vsprintf(funcNameBuffer, format, args);
va_end(args); va_end(args);
function = scriptJSON->child; function = scriptJSON->child;
while (function) while (function)
{ {
functionName = cJSON_GetObjectItem(function, "function")->valuestring; functionName = cJSON_GetObjectItem(function, "function")->valuestring;
if (strcmp(functionName, funcNameBuffer) == 0) if (strcmp(functionName, funcNameBuffer) == 0)
{ {
scriptRunner = malloc(sizeof(ScriptRunner)); scriptRunner = malloc(sizeof(ScriptRunner));
memset(scriptRunner, 0, sizeof(ScriptRunner)); memset(scriptRunner, 0, sizeof(ScriptRunner));
scriptRunner->line = cJSON_GetObjectItem(function, "lines")->child; scriptRunner->line = cJSON_GetObjectItem(function, "lines")->child;
tail->next = scriptRunner; tail->next = scriptRunner;
tail = scriptRunner; tail = scriptRunner;
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Running script '%s'", funcNameBuffer); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Running script '%s'", funcNameBuffer);
} }
function = function->next; function = function->next;
} }
} }
@ -118,7 +118,7 @@ static void executeNextLine(ScriptRunner *runner)
int intParam[2]; int intParam[2];
line = runner->line->valuestring; line = runner->line->valuestring;
sscanf(line, "%s", command); sscanf(line, "%s", command);
if (strcmp(command, "ACTIVATE_ENTITIES") == 0) if (strcmp(command, "ACTIVATE_ENTITIES") == 0)
@ -143,7 +143,7 @@ static void executeNextLine(ScriptRunner *runner)
} }
else if (strcmp(command, "ACTIVATE_JUMPGATE") == 0) else if (strcmp(command, "ACTIVATE_JUMPGATE") == 0)
{ {
battle.jumpgate->alive = ALIVE_ALIVE; battle.jumpgate->systemPower = MAX_SYSTEM_POWER;
} }
else if (strcmp(command, "MSG_BOX") == 0) else if (strcmp(command, "MSG_BOX") == 0)
{ {
@ -196,13 +196,13 @@ static void executeNextLine(ScriptRunner *runner)
void destroyScript(void) void destroyScript(void)
{ {
ScriptRunner *scriptRunner; ScriptRunner *scriptRunner;
while (head.next) while (head.next)
{ {
scriptRunner = head.next; scriptRunner = head.next;
head.next = scriptRunner->next; head.next = scriptRunner->next;
free(scriptRunner); free(scriptRunner);
} }
tail = &head; tail = &head;
} }

View File

@ -66,6 +66,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_FIGHTER_GUNS 12 #define MAX_FIGHTER_GUNS 12
#define MAX_TARGET_RANGE 65536 #define MAX_TARGET_RANGE 65536
#define MAX_SYSTEM_POWER 100
#define BATTLE_AREA_CELLS 50 #define BATTLE_AREA_CELLS 50
#define BATTLE_AREA_WIDTH (640 * BATTLE_AREA_CELLS) #define BATTLE_AREA_WIDTH (640 * BATTLE_AREA_CELLS)
@ -165,8 +166,7 @@ enum
ALIVE_ALIVE, ALIVE_ALIVE,
ALIVE_DYING, ALIVE_DYING,
ALIVE_DEAD, ALIVE_DEAD,
ALIVE_ESCAPED, ALIVE_ESCAPED
ALIVE_SLEEPING /* used by jumpgate */
}; };
enum enum

View File

@ -47,7 +47,7 @@ Mission *loadMissionMeta(char *filename)
text = readFile(filename); text = readFile(filename);
root = cJSON_Parse(text); root = cJSON_Parse(text);
mission = NULL; mission = NULL;
if (root) if (root)
@ -80,14 +80,14 @@ Mission *loadMissionMeta(char *filename)
if (node) if (node)
{ {
mission->challengeData.isChallenge = 1; mission->challengeData.isChallenge = 1;
/* limits */ /* limits */
mission->challengeData.timeLimit = getJSONValue(node, "timeLimit", 0) * FPS; mission->challengeData.timeLimit = getJSONValue(node, "timeLimit", 0) * FPS;
mission->challengeData.killLimit = getJSONValue(node, "killLimit", 0); mission->challengeData.killLimit = getJSONValue(node, "killLimit", 0);
mission->challengeData.escapeLimit = getJSONValue(node, "escapeLimit", 0); mission->challengeData.escapeLimit = getJSONValue(node, "escapeLimit", 0);
mission->challengeData.waypointLimit = getJSONValue(node, "waypointLimit", 0); mission->challengeData.waypointLimit = getJSONValue(node, "waypointLimit", 0);
mission->challengeData.itemLimit = getJSONValue(node, "itemLimit", 0); mission->challengeData.itemLimit = getJSONValue(node, "itemLimit", 0);
/* restrictions */ /* restrictions */
mission->challengeData.noMissiles = getJSONValue(node, "noMissiles", 0); mission->challengeData.noMissiles = getJSONValue(node, "noMissiles", 0);
mission->challengeData.noECM = getJSONValue(node, "noECM", 0); mission->challengeData.noECM = getJSONValue(node, "noECM", 0);
@ -121,7 +121,7 @@ Mission *loadMissionMeta(char *filename)
cJSON_Delete(root); cJSON_Delete(root);
} }
free(text); free(text);
return mission; return mission;
@ -223,7 +223,7 @@ void loadMission(char *filename)
initPlayer(); initPlayer();
initMissionInfo(); initMissionInfo();
addAllEntsToQuadtree(); addAllEntsToQuadtree();
playMusic(music); playMusic(music);
@ -567,7 +567,7 @@ static void loadEntities(cJSON *node)
{ {
Entity *e; Entity *e;
char *name, *groupName; char *name, *groupName;
int i, type, scatter, number, active, sleeping; int i, type, scatter, number, active, systemPower;
float x, y; float x, y;
if (node) if (node)
@ -588,7 +588,7 @@ static void loadEntities(cJSON *node)
number = getJSONValue(node, "number", 1); number = getJSONValue(node, "number", 1);
active = getJSONValue(node, "active", 1); active = getJSONValue(node, "active", 1);
scatter = getJSONValue(node, "scatter", 1); scatter = getJSONValue(node, "scatter", 1);
sleeping = getJSONValue(node, "sleeping", 0); systemPower = getJSONValue(node, "systemPower", MAX_SYSTEM_POWER);
for (i = 0 ; i < number ; i++) for (i = 0 ; i < number ; i++)
{ {
@ -628,11 +628,8 @@ static void loadEntities(cJSON *node)
} }
e->active = active; e->active = active;
if (sleeping) e->systemPower = systemPower;
{
e->alive = ALIVE_SLEEPING;
}
SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h); SDL_QueryTexture(e->texture, NULL, NULL, &e->w, &e->h);
} }

View File

@ -145,6 +145,7 @@ struct Entity {
Entity *leader; Entity *leader;
Entity *owner; Entity *owner;
void (*action)(void); void (*action)(void);
void (*draw)(void);
void (*die)(void); void (*die)(void);
SDL_Texture *texture; SDL_Texture *texture;
Entity *next; Entity *next;