Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monster icons #4365

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,46 @@ enum MagicEffectClasses : uint8_t
CONST_ME_FERUMBRAS_2 = 240,
};

enum MonsterIcon_t : uint8_t
{
MONSTER_ICON_NONE,
MONSTER_ICON_VULNERABLE,
MONSTER_ICON_WEAKENED,
MONSTER_ICON_MELEE,
MONSTER_ICON_INFLUENCED,
MONSTER_ICON_FIENDISH,

MONSTER_ICON_LAST
};

enum CreatureIcon_t : uint8_t
{
CREATURE_ICON_NONE,
CREATURE_ICON_CROSS_WHITE,
CREATURE_ICON_CROSS_WHITE_RED,
CREATURE_ICON_ORB_RED,
CREATURE_ICON_ORB_GREEN,
CREATURE_ICON_ORB_RED_GREEN,
CREATURE_ICON_GEM_GREEN,
CREATURE_ICON_GEM_YELLOW,
CREATURE_ICON_GEM_BLUE,
CREATURE_ICON_GEM_PURPLE,
CREATURE_ICON_GEM_RED,
CREATURE_ICON_PIGEON,
CREATURE_ICON_ENERGY,
CREATURE_ICON_POISON,
CREATURE_ICON_WATER,
CREATURE_ICON_FIRE,
CREATURE_ICON_ICE,
CREATURE_ICON_ARROW_UP,
CREATURE_ICON_ARROW_DOWN,
CREATURE_ICON_WARNING,
CREATURE_ICON_QUESTION,
CREATURE_ICON_CROSS_RED,

CREATURE_ICON_LAST
};

enum ShootType_t : uint8_t
{
CONST_ANI_NONE,
Expand Down
11 changes: 11 additions & 0 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ bool Creature::canSeeCreature(const Creature* creature) const
return true;
}

void Creature::refreshCreatureIcons() const
{
SpectatorVec spectators;
g_game.map.getSpectators(spectators, this->getPosition(), true, true);
for (Creature* spectator : spectators) {
if (auto player = spectator->getPlayer()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that here should also be verified in this way:

assert(dynamic_cast<Player*>(spectator) != nullptr);
static_cast<Player*>(spectator)->sendUpdateCreatureIcons(this);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spectator existing and being player is already verified in getSpectators (onlyPlayers param). Would be nice if PR author could at least mention where he got that code from.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk from where i took this code, it's possible it is your code :)
i have it for a while... :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

player->sendUpdateCreatureIcons(this);
}
}
}

void Creature::setSkull(Skulls_t newSkull)
{
skull = newSkull;
Expand Down
37 changes: 37 additions & 0 deletions src/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class Creature : virtual public Thing
virtual bool canSee(const Position& pos) const;
virtual bool canSeeCreature(const Creature* creature) const;

void refreshCreatureIcons() const;

virtual RaceType_t getRace() const { return RACE_NONE; }
virtual Skulls_t getSkull() const { return skull; }
virtual Skulls_t getSkullClient(const Creature* creature) const { return creature->getSkull(); }
Expand Down Expand Up @@ -166,6 +168,39 @@ class Creature : virtual public Thing
void setCurrentOutfit(Outfit_t outfit) { currentOutfit = outfit; }
const Outfit_t getDefaultOutfit() const { return defaultOutfit; }
bool isInvisible() const;

// creature icons
auto& getCreatureIcons() const { return creatureIcons; }

size_t getCreatureIconCount() const { return creatureIcons.size(); }

bool hasCreatureIcon(CreatureIcon_t iconId) { return creatureIcons.find(iconId) != creatureIcons.end(); }

uint16_t getCreatureIconValue(CreatureIcon_t iconId) { return hasCreatureIcon(iconId) ? creatureIcons[iconId] : 0; }

bool setCreatureIconValue(CreatureIcon_t iconId, uint16_t value)
{
if (iconId < CREATURE_ICON_LAST) {
creatureIcons[iconId] = value;
refreshCreatureIcons();
return true;
}

return false;
}

bool removeCreatureIcon(CreatureIcon_t iconId)
{
auto iter = creatureIcons.find(iconId);
if (iter == creatureIcons.end()) {
return false;
}

creatureIcons.erase(iter);
refreshCreatureIcons();
return true;
}

ZoneType_t getZone() const { return getTile()->getZone(); }

// walk functions
Expand Down Expand Up @@ -369,6 +404,8 @@ class Creature : virtual public Thing

std::vector<Direction> listWalkDir;

std::map<CreatureIcon_t, uint16_t> creatureIcons;

Tile* tile = nullptr;
Creature* attackedCreature = nullptr;
Creature* master = nullptr;
Expand Down
170 changes: 170 additions & 0 deletions src/luascript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,36 @@ void LuaScriptInterface::registerFunctions()
registerEnum(DECAYING_TRUE);
registerEnum(DECAYING_PENDING);

registerEnum(CREATURE_ICON_NONE);
registerEnum(CREATURE_ICON_CROSS_WHITE);
registerEnum(CREATURE_ICON_CROSS_WHITE_RED);
registerEnum(CREATURE_ICON_ORB_RED);
registerEnum(CREATURE_ICON_ORB_GREEN);
registerEnum(CREATURE_ICON_ORB_RED_GREEN);
registerEnum(CREATURE_ICON_GEM_GREEN);
registerEnum(CREATURE_ICON_GEM_YELLOW);
registerEnum(CREATURE_ICON_GEM_BLUE);
registerEnum(CREATURE_ICON_GEM_PURPLE);
registerEnum(CREATURE_ICON_GEM_RED);
registerEnum(CREATURE_ICON_PIGEON);
registerEnum(CREATURE_ICON_ENERGY);
registerEnum(CREATURE_ICON_POISON);
registerEnum(CREATURE_ICON_WATER);
registerEnum(CREATURE_ICON_FIRE);
registerEnum(CREATURE_ICON_ICE);
registerEnum(CREATURE_ICON_ARROW_UP);
registerEnum(CREATURE_ICON_ARROW_DOWN);
registerEnum(CREATURE_ICON_WARNING);
registerEnum(CREATURE_ICON_QUESTION);
registerEnum(CREATURE_ICON_CROSS_RED);

registerEnum(MONSTER_ICON_NONE);
registerEnum(MONSTER_ICON_VULNERABLE);
registerEnum(MONSTER_ICON_WEAKENED);
registerEnum(MONSTER_ICON_MELEE);
registerEnum(MONSTER_ICON_INFLUENCED);
registerEnum(MONSTER_ICON_FIENDISH);

// _G
registerGlobalVariable("INDEX_WHEREEVER", INDEX_WHEREEVER);
registerGlobalBoolean("VIRTUAL_PARENT", true);
Expand Down Expand Up @@ -2527,6 +2557,11 @@ void LuaScriptInterface::registerFunctions()

registerMethod("Creature", "getZone", LuaScriptInterface::luaCreatureGetZone);

registerMethod("Creature", "hasIcon", LuaScriptInterface::luaCreatureHasIcon);
registerMethod("Creature", "getIconValue", LuaScriptInterface::luaCreatureGetIconValue);
registerMethod("Creature", "setIconValue", LuaScriptInterface::luaCreatureSetIconValue);
registerMethod("Creature", "removeIcon", LuaScriptInterface::luaCreatureRemoveIcon);

// Player
registerClass("Player", "Creature", LuaScriptInterface::luaPlayerCreate);
registerMetaMethod("Player", "__eq", LuaScriptInterface::luaUserdataCompare);
Expand Down Expand Up @@ -2743,6 +2778,11 @@ void LuaScriptInterface::registerFunctions()
registerMethod("Monster", "isWalkingToSpawn", LuaScriptInterface::luaMonsterIsWalkingToSpawn);
registerMethod("Monster", "walkToSpawn", LuaScriptInterface::luaMonsterWalkToSpawn);

registerMethod("Monster", "hasMonsterIcon", LuaScriptInterface::luaMonsterHasIcon);
registerMethod("Monster", "getMonsterIconValue", LuaScriptInterface::luaMonsterGetIconValue);
registerMethod("Monster", "setMonsterIconValue", LuaScriptInterface::luaMonsterSetIconValue);
registerMethod("Monster", "removeMonsterIcon", LuaScriptInterface::luaMonsterRemoveIcon);

// Npc
registerClass("Npc", "Creature", LuaScriptInterface::luaNpcCreate);
registerMetaMethod("Npc", "__eq", LuaScriptInterface::luaUserdataCompare);
Expand Down Expand Up @@ -8615,6 +8655,71 @@ int LuaScriptInterface::luaCreatureGetZone(lua_State* L)
return 1;
}

int LuaScriptInterface::luaCreatureHasIcon(lua_State* L)
Copy link
Contributor

@MillhioreBT MillhioreBT Apr 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should follow the format of the other methods:

if (!userdata) {
lua_pushnil();
return 1;
}

-- Code

{
// creature:hasIcon(iconId)
Creature* monster = getUserdata<Creature>(L, 1);
if (monster) {
CreatureIcon_t iconId = getNumber<CreatureIcon_t>(L, 2);
if (iconId < CREATURE_ICON_LAST) {
pushBoolean(L, monster->hasCreatureIcon(iconId));
return 1;
}
}

lua_pushnil(L);
return 1;
}

int LuaScriptInterface::luaCreatureGetIconValue(lua_State* L)
{
// creature:getIconValue(iconId)
Creature* monster = getUserdata<Creature>(L, 1);
if (monster) {
CreatureIcon_t iconId = getNumber<CreatureIcon_t>(L, 2);
if (iconId < CREATURE_ICON_LAST) {
lua_pushnumber(L, monster->getCreatureIconValue(iconId));
return 1;
}
}

lua_pushnil(L);
return 1;
}

int LuaScriptInterface::luaCreatureSetIconValue(lua_State* L)
{
// creature:setIconValue(iconId, value)
Creature* monster = getUserdata<Creature>(L, 1);
if (monster) {
CreatureIcon_t iconId = getNumber<CreatureIcon_t>(L, 2);
if (iconId < CREATURE_ICON_LAST) {
uint16_t value = getNumber<uint16_t>(L, 3);
lua_pushnumber(L, monster->setCreatureIconValue(iconId, value));
return 1;
}
}

lua_pushnil(L);
return 1;
}

int LuaScriptInterface::luaCreatureRemoveIcon(lua_State* L)
{
// creature:removeIcon(iconId)
Creature* monster = getUserdata<Creature>(L, 1);
if (monster) {
CreatureIcon_t iconId = getNumber<CreatureIcon_t>(L, 2);
if (iconId < CREATURE_ICON_LAST) {
pushBoolean(L, monster->removeCreatureIcon(iconId));
return 1;
}
}

lua_pushnil(L);
return 1;
}

// Player
int LuaScriptInterface::luaPlayerCreate(lua_State* L)
{
Expand Down Expand Up @@ -11201,6 +11306,71 @@ int LuaScriptInterface::luaMonsterWalkToSpawn(lua_State* L)
return 1;
}

int LuaScriptInterface::luaMonsterHasIcon(lua_State* L)
{
// monster:hasMonsterIcon(iconId)
Monster* monster = getUserdata<Monster>(L, 1);
if (monster) {
MonsterIcon_t iconId = getNumber<MonsterIcon_t>(L, 2);
if (iconId < MONSTER_ICON_LAST) {
pushBoolean(L, monster->hasMonsterIcon(iconId));
return 1;
}
}

lua_pushnil(L);
return 1;
}

int LuaScriptInterface::luaMonsterGetIconValue(lua_State* L)
{
// monster:getMonsterIconValue(iconId)
Monster* monster = getUserdata<Monster>(L, 1);
if (monster) {
MonsterIcon_t iconId = getNumber<MonsterIcon_t>(L, 2);
if (iconId < MONSTER_ICON_LAST) {
lua_pushnumber(L, monster->getMonsterIconValue(iconId));
return 1;
}
}

lua_pushnil(L);
return 1;
}

int LuaScriptInterface::luaMonsterSetIconValue(lua_State* L)
{
// monster:setMonsterIconValue(iconId, value)
Monster* monster = getUserdata<Monster>(L, 1);
if (monster) {
MonsterIcon_t iconId = getNumber<MonsterIcon_t>(L, 2);
if (iconId < MONSTER_ICON_LAST) {
uint16_t value = getNumber<uint16_t>(L, 3);
lua_pushnumber(L, monster->setMonsterIconValue(iconId, value));
return 1;
}
}

lua_pushnil(L);
return 1;
}

int LuaScriptInterface::luaMonsterRemoveIcon(lua_State* L)
{
// monster:removeMonsterIcon(iconId)
Monster* monster = getUserdata<Monster>(L, 1);
if (monster) {
MonsterIcon_t iconId = getNumber<MonsterIcon_t>(L, 2);
if (iconId < MONSTER_ICON_LAST) {
pushBoolean(L, monster->removeMonsterIcon(iconId));
return 1;
}
}

lua_pushnil(L);
return 1;
}

// Npc
int LuaScriptInterface::luaNpcCreate(lua_State* L)
{
Expand Down
10 changes: 10 additions & 0 deletions src/luascript.h
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,11 @@ class LuaScriptInterface

static int luaCreatureGetZone(lua_State* L);

static int luaCreatureHasIcon(lua_State* L);
static int luaCreatureGetIconValue(lua_State* L);
static int luaCreatureSetIconValue(lua_State* L);
static int luaCreatureRemoveIcon(lua_State* L);

// Player
static int luaPlayerCreate(lua_State* L);

Expand Down Expand Up @@ -1047,6 +1052,11 @@ class LuaScriptInterface
static int luaMonsterIsWalkingToSpawn(lua_State* L);
static int luaMonsterWalkToSpawn(lua_State* L);

static int luaMonsterHasIcon(lua_State* L);
static int luaMonsterGetIconValue(lua_State* L);
static int luaMonsterSetIconValue(lua_State* L);
static int luaMonsterRemoveIcon(lua_State* L);

// Npc
static int luaNpcCreate(lua_State* L);

Expand Down
34 changes: 34 additions & 0 deletions src/monster.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,38 @@ class Monster final : public Creature
BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage, bool checkDefense = false,
bool checkArmor = false, bool field = false, bool ignoreResistances = false) override;

// monster icons
auto& getMonsterIcons() const { return monsterIcons; }

size_t getMonsterIconCount() const { return monsterIcons.size(); }

bool hasMonsterIcon(MonsterIcon_t iconId) { return monsterIcons.find(iconId) != monsterIcons.end(); }

uint16_t getMonsterIconValue(MonsterIcon_t iconId) { return hasMonsterIcon(iconId) ? monsterIcons[iconId] : 0; }

bool setMonsterIconValue(MonsterIcon_t iconId, uint16_t value)
{
if (iconId < MONSTER_ICON_LAST) {
monsterIcons[iconId] = value;
refreshCreatureIcons();
return true;
}

return false;
}

bool removeMonsterIcon(MonsterIcon_t iconId)
{
auto iter = monsterIcons.find(iconId);
if (iter == monsterIcons.end()) {
return false;
}

monsterIcons.erase(iter);
refreshCreatureIcons();
return true;
}

static uint32_t monsterAutoID;

private:
Expand Down Expand Up @@ -158,6 +190,8 @@ class Monster final : public Creature
bool randomStepping = false;
bool walkingToSpawn = false;

std::map<MonsterIcon_t, uint16_t> monsterIcons;

void onCreatureEnter(Creature* creature);
void onCreatureLeave(Creature* creature);
void onCreatureFound(Creature* creature, bool pushFront = false);
Expand Down
Loading