Compare commits
2 Commits
861457fdaf
...
c786d35388
Author | SHA1 | Date |
---|---|---|
Lephenixnoir | c786d35388 | |
Lephenixnoir | cfb92c175d |
|
@ -156,6 +156,12 @@ set(ASSETS
|
|||
# Enemies: Washing machine
|
||||
assets-cg/enemies/washing_machine_left.aseprite
|
||||
assets-cg/enemies/washing_machine_right.aseprite
|
||||
# Enemies: Water slime
|
||||
assets-cg/enemies/water_slime_left.txt
|
||||
assets-cg/enemies/water_slime_right.txt
|
||||
# Enemies: Chemical slime
|
||||
assets-cg/enemies/chemical_slime_left.txt
|
||||
assets-cg/enemies/chemical_slime_right.txt
|
||||
# Misc
|
||||
assets-cg/font_damage_red.png
|
||||
assets-cg/font_damage_white.png
|
||||
|
|
5
TODO
5
TODO
|
@ -39,14 +39,13 @@ Core mechanics:
|
|||
|
||||
Content:
|
||||
* Additional skills
|
||||
* Give the chemical slime a magic attack
|
||||
* Jump attacks for elemental slimes
|
||||
|
||||
Infrastructure:
|
||||
* Better end screen
|
||||
* Save and load scores (including with bindings)
|
||||
|
||||
Bugfixes:
|
||||
* Fix ability to attack continuously by holding SHIFT
|
||||
|
||||
Extra details
|
||||
=============
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ MONSTER_IDS = {
|
|||
"fire_slime/4": 3,
|
||||
"albinos_bat/6": 4,
|
||||
"gunslinger/8": 5,
|
||||
"water_slime/8": 6,
|
||||
"chemical_slime/10": 7,
|
||||
}
|
||||
ITEM_IDS = {
|
||||
"life": 0,
|
||||
|
|
16
src/aoe.c
16
src/aoe.c
|
@ -87,7 +87,9 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, vec2 dir)
|
|||
distance = fix(0.375);
|
||||
lifetime = fix(999.0);
|
||||
}
|
||||
else if(type == AOE_FIRE_CHARGE) {
|
||||
else if(type == AOE_FIRE_CHARGE
|
||||
|| type == AOE_WATER_CHARGE
|
||||
|| type == AOE_CHEMICAL_CHARGE) {
|
||||
anim = NULL;
|
||||
hitbox = (rect){ -fix(12)/16, fix(12)/16, -fix(13)/16, fix(2)/16 };
|
||||
distance = fix(0);
|
||||
|
@ -147,7 +149,9 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, vec2 dir)
|
|||
v->z = fix(0.5);
|
||||
v->shadow_size = 4;
|
||||
}
|
||||
else if(type == AOE_FIRE_CHARGE) {
|
||||
else if(type == AOE_FIRE_CHARGE
|
||||
|| type == AOE_WATER_CHARGE
|
||||
|| type == AOE_CHEMICAL_CHARGE) {
|
||||
aoe->data.charge.element = 0;
|
||||
aoe->data.charge.power = f->MAG;
|
||||
aoe->data.charge.origin = physical_pos(origin);
|
||||
|
@ -234,7 +238,9 @@ static bool attack_apply(game_t *game, aoe_t *aoe, entity_t *target)
|
|||
/* TODO: Sideways knockback */
|
||||
damage = aoe->data.bullet.strength * 3 / 2;
|
||||
}
|
||||
else if(aoe->type == AOE_FIRE_CHARGE) {
|
||||
else if(aoe->type == AOE_FIRE_CHARGE
|
||||
|| aoe->type == AOE_WATER_CHARGE
|
||||
|| aoe->type == AOE_CHEMICAL_CHARGE) {
|
||||
dir.x = target_p->x - aoe->data.charge.origin.x;
|
||||
dir.y = target_p->y - aoe->data.charge.origin.y;
|
||||
dir = fnormalize(dir);
|
||||
|
@ -292,7 +298,9 @@ void aoe_apply(game_t *game, entity_t *entity, entity_t *e)
|
|||
|| aoe->type == AOE_IMPALE
|
||||
|| aoe->type == AOE_SHOCK
|
||||
|| aoe->type == AOE_BULLET
|
||||
|| aoe->type == AOE_FIRE_CHARGE)
|
||||
|| aoe->type == AOE_FIRE_CHARGE
|
||||
|| aoe->type == AOE_WATER_CHARGE
|
||||
|| aoe->type == AOE_CHEMICAL_CHARGE)
|
||||
was_hit = attack_apply(game, aoe, e);
|
||||
|
||||
if(aoe->type == AOE_JUDGEMENT) {
|
||||
|
|
|
@ -25,6 +25,8 @@ enum {
|
|||
AOE_JUDGEMENT,
|
||||
AOE_BULLET,
|
||||
AOE_FIRE_CHARGE,
|
||||
AOE_WATER_CHARGE,
|
||||
AOE_CHEMICAL_CHARGE,
|
||||
/* Spawn effect */
|
||||
EFFECT_SPAWN,
|
||||
};
|
||||
|
|
|
@ -118,12 +118,54 @@ static enemy_t const gunslinger_8 = {
|
|||
.ai_data_size = 0,
|
||||
};
|
||||
|
||||
static enemy_t const water_slime_8 = {
|
||||
.name = "Water slime",
|
||||
.level = 8,
|
||||
ANIMS(water_slime, Idle, Walking, Attack, Hit, Death),
|
||||
.hitbox = (rect){ -fix(3)/16, fix(4)/16, -fix(2)/16, fix(3)/16 },
|
||||
.limits = {
|
||||
.max_speed = fix(1.2),
|
||||
.friction = fix(0.4),
|
||||
.max_disruption_speed = fix(999.0),
|
||||
},
|
||||
/* Same as slime/1 */
|
||||
.stats_base = { .HP=10, .ATK=8, .MAG=5, .DEF=5 },
|
||||
.stats_growth = { .HP=8, .ATK=4, .MAG=4, .DEF=2 },
|
||||
|
||||
.shadow_size = 4,
|
||||
.xp = 24,
|
||||
.z = 0,
|
||||
.ai_data_size = 0,
|
||||
};
|
||||
|
||||
static enemy_t const chemical_slime_10 = {
|
||||
.name = "Chemical slime",
|
||||
.level = 10,
|
||||
ANIMS(chemical_slime, Idle, Walking, Attack, Hit, Death),
|
||||
.hitbox = (rect){ -fix(3)/16, fix(4)/16, -fix(2)/16, fix(3)/16 },
|
||||
.limits = {
|
||||
.max_speed = fix(0.6),
|
||||
.friction = fix(0.8),
|
||||
.max_disruption_speed = fix(999.0),
|
||||
},
|
||||
/* Like as slime/1 but boosted MAG over ATK */
|
||||
.stats_base = { .HP=10, .ATK=8, .MAG=5, .DEF=5 },
|
||||
.stats_growth = { .HP=8, .ATK=2, .MAG=6, .DEF=2 },
|
||||
|
||||
.shadow_size = 4,
|
||||
.xp = 41,
|
||||
.z = 0,
|
||||
.ai_data_size = 0,
|
||||
};
|
||||
|
||||
static enemy_t const * const enemies[] = {
|
||||
[ENEMY_SLIME_1] = &slime_1,
|
||||
[ENEMY_BAT_2] = &bat_2,
|
||||
[ENEMY_FIRE_SLIME_4] = &fire_slime_4,
|
||||
[ENEMY_ALBINOS_BAT_6] = &albinos_bat_6,
|
||||
[ENEMY_GUNSLINGER_8] = &gunslinger_8,
|
||||
[ENEMY_SLIME_1] = &slime_1,
|
||||
[ENEMY_BAT_2] = &bat_2,
|
||||
[ENEMY_FIRE_SLIME_4] = &fire_slime_4,
|
||||
[ENEMY_ALBINOS_BAT_6] = &albinos_bat_6,
|
||||
[ENEMY_GUNSLINGER_8] = &gunslinger_8,
|
||||
[ENEMY_WATER_SLIME_8] = &water_slime_8,
|
||||
[ENEMY_CHEMICAL_SLIME_10] = &chemical_slime_10,
|
||||
};
|
||||
|
||||
enemy_t const *enemy_data(int enemy_id)
|
||||
|
@ -195,6 +237,12 @@ entity_t *enemy_make(int enemy_id)
|
|||
else if(enemy_id == ENEMY_GUNSLINGER_8) {
|
||||
f->skills[0] = AOE_PROJECTILE;
|
||||
}
|
||||
else if(enemy_id == ENEMY_WATER_SLIME_8) {
|
||||
f->skills[1] = AOE_WATER_CHARGE;
|
||||
}
|
||||
else if(enemy_id == ENEMY_CHEMICAL_SLIME_10) {
|
||||
f->skills[1] = AOE_CHEMICAL_CHARGE;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
@ -338,11 +386,17 @@ void enemy_ai(game_t *g, entity_t *e, fixed_t dt)
|
|||
}
|
||||
}
|
||||
|
||||
else if(f->enemy->id == &fire_slime_4) {
|
||||
else if(f->enemy->id == &fire_slime_4 || f->enemy->id == &water_slime_8
|
||||
|| f->enemy->id == &chemical_slime_10) {
|
||||
if(move_within_range_of_player(g, e, fix(0.75), dt)) {
|
||||
/* Use the fire charge attack; if it fails, normal attack */
|
||||
if(use_skill_towards_player(g, e, 1)) {
|
||||
visible_set_anim(e, &anims_fire_slime_Fire, 2);
|
||||
if(f->enemy->id == &fire_slime_4)
|
||||
visible_set_anim(e, &anims_fire_slime_Fire, 2);
|
||||
if(f->enemy->id == &water_slime_8)
|
||||
visible_set_anim(e, &anims_water_slime_Fire, 2);
|
||||
if(f->enemy->id == &chemical_slime_10)
|
||||
visible_set_anim(e, &anims_chemical_slime_Fire, 2);
|
||||
}
|
||||
else {
|
||||
contact_attack(g, e);
|
||||
|
|
|
@ -40,11 +40,13 @@ typedef struct
|
|||
/* List of enemies */
|
||||
enum {
|
||||
/* ID 0 is used for the player! */
|
||||
ENEMY_SLIME_1 = 1,
|
||||
ENEMY_BAT_2 = 2,
|
||||
ENEMY_FIRE_SLIME_4 = 3,
|
||||
ENEMY_ALBINOS_BAT_6 = 4,
|
||||
ENEMY_GUNSLINGER_8 = 5,
|
||||
ENEMY_SLIME_1 = 1,
|
||||
ENEMY_BAT_2 = 2,
|
||||
ENEMY_FIRE_SLIME_4 = 3,
|
||||
ENEMY_ALBINOS_BAT_6 = 4,
|
||||
ENEMY_GUNSLINGER_8 = 5,
|
||||
ENEMY_WATER_SLIME_8 = 6,
|
||||
ENEMY_CHEMICAL_SLIME_10 = 7,
|
||||
};
|
||||
|
||||
/* Dynamic enemy information. */
|
||||
|
|
|
@ -340,7 +340,7 @@ static int menu_select_play_repeat(void)
|
|||
|
||||
key_event_t ev;
|
||||
while((ev = pollevent()).type != KEYEV_NONE) {
|
||||
if(ev.type == KEYEV_UP) continue;
|
||||
if(ev.type != KEYEV_DOWN) continue;
|
||||
|
||||
if(ev.key == KEY_MENU)
|
||||
gint_osmenu();
|
||||
|
|
|
@ -22,7 +22,9 @@ fixed_t skill_cooldown(int skill)
|
|||
return fix(3.0);
|
||||
else if(skill == AOE_BULLET)
|
||||
return fix(4.0);
|
||||
else if(skill == AOE_FIRE_CHARGE)
|
||||
else if(skill == AOE_FIRE_CHARGE
|
||||
|| skill == AOE_WATER_CHARGE
|
||||
|| skill == AOE_CHEMICAL_CHARGE)
|
||||
return fix(3.0);
|
||||
|
||||
return fix(0.0);
|
||||
|
@ -108,7 +110,8 @@ bool skill_use(game_t *game, entity_t *e, int slot, vec2 dir)
|
|||
visible_set_anim(e, f->enemy->id->anim_attack, 2);
|
||||
}
|
||||
else if(skill == AOE_FIRE_CHARGE
|
||||
/* || skill == AOE_WATER_CHARGE */) {
|
||||
|| skill == AOE_WATER_CHARGE
|
||||
|| skill == AOE_CHEMICAL_CHARGE) {
|
||||
if(f->current_attack)
|
||||
return false;
|
||||
entity_t *aoe = aoe_make_attack(skill, e, dir);
|
||||
|
|
|
@ -18,6 +18,8 @@ enum {
|
|||
// AOE_JUDGEMENT,
|
||||
// AOE_BULLET,
|
||||
// AOE_FIRE_CHARGE,
|
||||
// AOE_WATER_CHARGE,
|
||||
// AOE_CHEMICAL_CHARGE,
|
||||
};
|
||||
|
||||
/* Fixed cooldown for a skill */
|
||||
|
|
Loading…
Reference in New Issue