Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Enemies now regenerate health slower after being hit, making dealing …

…with multiple enemies much more feasible
  • Loading branch information...
commit dcfd07ce10edc94868f5db85741336dbadad4d94 1 parent f4aa26e
@ludamad authored
View
2  HACKING/TODO
@@ -0,0 +1,2 @@
+- Refactor the sidebar into Lua, starting with the inventory
+- Refactor CombatGameInst so the differences between enemies and players is merely a matter of 'status effects'
View
41 res/sidebar/inventory_draw.lua
@@ -0,0 +1,41 @@
+require "utils"
+require "InstanceBox"
+require "InstanceLine"
+require "TextInputBox"
+require "TextLabel"
+require "Sprite"
+
+DEBUG_LAYOUTS = false
+
+-- Need to expose inventory to Lua ??
+
+function inventory_view_create(size)
+ local box = InstanceBox.create( { size = size } )
+ function box:draw(xy) -- makeshift inheritance
+ local bbox = bbox_create(xy, self.size)
+ draw_rectangle_outline(COL_WHITE, bbox, 1)
+ end
+ return box
+end
+
+function main()
+ local size = {160, 300}
+ local inv = inventory_view_create(size)
+
+ while game.input_capture() and not key_pressed(keys.ESCAPE) do
+ if key_pressed(keys.F9) then
+ -- note, globals are usually protected against being changed
+ -- but a bypass is allowed for cases where it must be done
+ setglobal("DEBUG_LAYOUTS", not DEBUG_LAYOUTS) -- flip on/off
+ end
+
+ display.draw_start()
+ inv:draw( {100, 100} )
+ display.draw_finish()
+
+ io.flush()
+ game.wait(10)
+ end
+
+ return false -- User has quit the game
+end
View
1  res/start_menu/start_menu.lua
@@ -205,7 +205,6 @@ local function menu_loop(should_poll)
net.connections_poll()
end
-
menu_state.menu:step( {0, 0} )
if key_pressed(keys.ENTER) and menu_state.continue then
View
6 settings.yaml
@@ -2,9 +2,9 @@
username: User
#Window settings
-fullscreen: no
-view_width: 640
-view_height: 480
+fullscreen: yes
+view_width: 1600
+view_height: 900
#Gameplay preferences
autouse_health_potions: yes # can toggle in game as well
View
4 src/lanarts/src/objects/CombatGameInst.cpp
@@ -32,7 +32,6 @@ bool CombatGameInst::damage(GameState* gs, int dmg) {
die(gs);
return true;
}
- signal_was_damaged();
cooldowns().reset_hurt_cooldown(HURT_COOLDOWN);
return false;
}
@@ -64,8 +63,9 @@ void CombatGameInst::update_field_of_view(GameState* gs) {
void CombatGameInst::step(GameState* gs) {
estats = stats().effective_stats(gs, this);
stats().step(gs, this, estats);
+
// XXX: If we do not sync the new mp & hp values
- // we can get drawing artifacts
+ // we can get health/mp bars that look more than full
estats.core.hp = stats().core.hp;
estats.core.mp = stats().core.mp;
}
View
5 src/lanarts/src/objects/CombatGameInst.h
@@ -55,7 +55,7 @@ class CombatGameInst: public GameInst {
void update_position();
virtual void update_position(float newx, float newy);
- bool damage(GameState* gs, int dmg);
+ virtual bool damage(GameState* gs, int dmg);
bool damage(GameState* gs, const EffectiveAttackStats& attack);
bool melee_attack(GameState* gs, CombatGameInst* inst,
const Weapon& weapon, bool ignore_cooldowns = false);
@@ -66,8 +66,7 @@ class CombatGameInst: public GameInst {
virtual void signal_attacked_successfully() {
}
- virtual void signal_was_damaged() {
- }
+
virtual void signal_killed_enemy() {
kills++;
}
View
4 src/lanarts/src/objects/enemy/EnemyBehaviour.h
@@ -83,6 +83,10 @@ struct EnemyBehaviour {
randomization.step();
}
+ void damage_was_taken() {
+ randomization.damage_taken_timer = 0;
+ }
+
void serialize(GameState* gs, SerializeBuffer& serializer);
void deserialize(GameState* gs, SerializeBuffer& serializer);
};
View
68 src/lanarts/src/objects/enemy/EnemyInst.cpp
@@ -51,17 +51,21 @@ float monster_difficulty_multiplier(GameState* gs, EnemyEntry& etype) {
if (size > 6) {
size = 6; // A group larger than 6 will probably be split up considerably
}
- float mult = log(size);//NB: natural log, base e ~ 2.718...
+ float mult = log(size); //NB: natural log, base e ~ 2.718...
if (etype.unique) {
- return 1+mult / 8; // Can reasonably expect all players to be part of a boss fight
+ return 1 + mult / 8; // Can reasonably expect all players to be part of a boss fight
}
- return 1+mult / 16;
+ return 1 + mult / 16;
}
EnemyInst::EnemyInst(int enemytype, int x, int y, int teamid, int mobid) :
- CombatGameInst(__E(enemytype).basestats, __E(enemytype).enemy_sprite,
- teamid, mobid, x, y, __E(enemytype).radius, true, DEPTH), seen(
- false), enemytype(enemytype), xpgain(__E(enemytype).xpaward) {
+ CombatGameInst(__E(enemytype).basestats,
+ __E(enemytype).enemy_sprite, teamid, mobid, x, y,
+ __E(enemytype).radius, true, DEPTH) {
+ this->seen = false;
+ this->xpgain = __E(enemytype).xpaward;
+ this->enemytype = enemytype;
+ this->enemy_regen_cooloff = 0;
}
EnemyInst::~EnemyInst() {
@@ -80,10 +84,6 @@ void EnemyInst::signal_attacked_successfully() {
eb.randomization.successful_hit_timer = 0;
}
-void EnemyInst::signal_was_damaged() {
- eb.randomization.damage_taken_timer = 0;
-}
-
unsigned int EnemyInst::integrity_hash() {
unsigned int hash = CombatGameInst::integrity_hash();
combine_hash(hash, eb.current_node, eb.path_steps);
@@ -102,7 +102,6 @@ void EnemyInst::serialize(GameState* gs, SerializeBuffer& serializer) {
// ai_state.serialize(gs, serializer);
}
-
void EnemyInst::deserialize(GameState* gs, SerializeBuffer& serializer) {
CombatGameInst::deserialize(gs, serializer);
serializer.read(seen);
@@ -114,6 +113,14 @@ void EnemyInst::deserialize(GameState* gs, SerializeBuffer& serializer) {
target_radius, effective_stats().movespeed);
// ai_state.deserialize(gs, serializer);
}
+
+bool EnemyInst::damage(GameState* gs, int dmg) {
+ eb.damage_was_taken();
+ enemy_regen_cooloff += dmg;
+
+ return CombatGameInst::damage(gs, dmg);
+}
+
EnemyEntry& EnemyInst::etype() {
return game_enemy_data.at(enemytype);
}
@@ -159,7 +166,19 @@ static void show_defeat_message(GameChat& chat, EnemyEntry& e) {
void EnemyInst::step(GameState* gs) {
//Much of the monster implementation resides in MonsterController
+
+// XXX: Make the monster health absorbing way less hackish and more general
+ int hp_before = stats().core.hp;
+
CombatGameInst::step(gs);
+
+ // Absorb health regen if recently damaged
+ int hp_gain = stats().core.hp - hp_before;
+ int hp_cooloff = std::min(enemy_regen_cooloff, hp_gain);
+ enemy_regen_cooloff -= hp_cooloff;
+ stats().core.hp -= hp_cooloff;
+ effective_stats().core.hp = stats().core.hp;
+
update_position();
if (!seen && gs->object_visible_test(this, gs->local_player())) {
@@ -175,17 +194,15 @@ void EnemyInst::draw(GameState* gs) {
if (gs->game_settings().draw_diagnostics) {
char statbuff[255];
- snprintf(
- statbuff,
- 255,
+ snprintf(statbuff, 255,
"simid=%d nvx=%f vy=%f\n chasetime=%d \n mdef=%d pdef=%d", // \n act=%d, path_steps = %d\npath_cooldown = %d\n",
simulation_id, vx, vy, eb.chase_timeout,
- (int)effective_stats().magic.resistance,
- (int)effective_stats().physical.resistance);
+ (int) effective_stats().magic.resistance,
+ (int) effective_stats().physical.resistance);
//eb.current_action,
//eb.path_steps, eb.path_cooldown);
- gs->font().draw(COL_WHITE,
- Pos(x - radius - view.x, y - 70 - view.y), statbuff);
+ gs->font().draw(COL_WHITE, Pos(x - radius - view.x, y - 70 - view.y),
+ statbuff);
}
int w = spr.size().w, h = spr.size().h;
@@ -196,23 +213,18 @@ void EnemyInst::draw(GameState* gs) {
if (!gs->object_visible_test(this))
return;
-// TODO: fix enemy mouseover descriptions ?
-// BBox ebox(xx, yy, xx + w, yy + h);
-// if (ebox.contains(gs->mouse_x() + view.x, gs->mouse_y() + view.y)) {
-// draw_console_enemy_description(gs, etype());
-// }
-
if (etype().draw_event.empty()) {
float frame = gs->frame();
if (etype().name == "Hydra") {
- frame = floor( core_stats().hp / float(core_stats().max_hp) * 4);
- if (frame >= 4) frame = 4;
+ frame = floor(core_stats().hp / float(core_stats().max_hp) * 4);
+ if (frame >= 4)
+ frame = 4;
}
CombatGameInst::draw(gs, frame);
} else {
lua_State* L = gs->luastate();
etype().draw_event.get(L).push();
- luawrap::call<void>(L, (GameInst*)this);
+ luawrap::call<void>(L, (GameInst*) this);
}
}
@@ -247,5 +259,5 @@ void EnemyInst::die(GameState *gs) {
void EnemyInst::copy_to(GameInst *inst) const {
LANARTS_ASSERT(typeid(*this) == typeid(*inst));
- *(EnemyInst*)inst = *this;
+ *(EnemyInst*) inst = *this;
}
View
7 src/lanarts/src/objects/enemy/EnemyInst.h
@@ -27,8 +27,9 @@ class EnemyInst : public CombatGameInst {
virtual void copy_to(GameInst* inst) const;
virtual EnemyInst* clone() const;
+ virtual bool damage(GameState* gs, int dmg);
+
virtual void signal_attacked_successfully();
- virtual void signal_was_damaged();
virtual unsigned int integrity_hash();
@@ -42,10 +43,12 @@ class EnemyInst : public CombatGameInst {
int xpworth(){
return xpgain;
}
-protected:
+
+private:
bool seen;
int enemytype;
EnemyBehaviour eb;
+ int enemy_regen_cooloff;
// EnemyAIState ai_state;
int xpgain;
};
Please sign in to comment.
Something went wrong with that request. Please try again.