/*
 *  monsters.h - Monsters.
 *
 *  Copyright (C) 2000-2022  The Exult Team
 *
 *  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.
 */

#ifndef INCL_MONSTERS
#define INCL_MONSTERS 1

#include "actors.h"
#include "ignore_unused_variable_warning.h"

class Monster_actor;

/*
 *  Monsters get their own class because they have a bigger footprint
 *  than humans.
 */
class Monster_actor : public Npc_actor {
	static Game_object_shared in_world;    // All monsters in the world.
										   // Links for 'in_world' list.
	Game_object_shared next_monster;
	Monster_actor*     prev_monster;
	Animator*          animator;      // For wounded men.
	void               link_in();     // Add to in_world list.
	void               link_out();    // Remove from list.
	void               equip(const Monster_info* inf, bool temporary);

public:
	Monster_actor(
			const std::string& nm, int shapenum, int num = -1, int uc = -1);
	~Monster_actor() override;
	// Create an instance.
	static Game_object_shared create(int shnum);
	static Game_object_shared create(
			int shnum, Tile_coord pos, int sched = -1,
			int align = static_cast<int>(Actor::neutral), bool temporary = true,
			bool equipment = true);

	// Methods to retrieve them all:
	static Monster_actor* get_first_in_world() {
		return in_world ? static_cast<Monster_actor*>(in_world.get()) : nullptr;
	}

	Monster_actor* get_next_in_world() {
		return next_monster ? static_cast<Monster_actor*>(next_monster.get())
							: nullptr;
	}

	static void delete_all();    // Delete all monsters.

	static void give_up() {    // For file errors only!
		in_world = nullptr;
	}

	bool move_aside(Actor* for_actor, int dir) override {
		ignore_unused_variable_warning(for_actor, dir);
		return false;    // Monsters don't move aside.
	}

	// Render.
	void paint() override;
	// Step onto an (adjacent) tile.
	bool step(Tile_coord t, int frame, bool force = false) override;
	// Remove/delete this object.
	void remove_this(Game_object_shared* keep = nullptr) override;
	// Move to new abs. location.
	void move(int newtx, int newty, int newlift, int newmap = -1) override;
	// Add an object.
	bool add(
			Game_object* obj, bool dont_check = false, bool combine = false,
			bool noset = false) override;
	int get_armor_points() const override;    // Get total armor value.
											  // Get total weapon value.
	const Weapon_info* get_weapon(
			int& points, int& shape, Game_object*& obj) const override;

	bool is_monster() const override {
		return true;
	}

	void die(Game_object* attacker) override;    // We're dead.
	void write(ODataSource* nfile);    // Write out (to 'monsnpc.dat').
};

#endif
