Jump to content
  • Creature


    Arkadus
    • Status: In Progress
      Main Category: Script (Eluna / SD3)
      Sub-Category: sd2
      Version: 0.20 Milestone: 20 Priority: Normal
      Implemented Version: 0.20

    Creature

    Creature.cpp file

    bool Creature::InitEntry(uint32 Entry, Team team, CreatureData const* data /*=NULL*/, GameEventCreatureData const* eventData /*=NULL*/)
    {
    // use game event entry if any instead default suggested
    if (eventData && eventData->entry_id)
    { Entry = eventData->entry_id; }

    CreatureInfo const* normalInfo = ObjectMgr::GetCreatureTemplate(Entry);
    if (!normalInfo)
    {
    sLog.outErrorDb("Creature::UpdateEntry creature entry %u does not exist.", Entry);
    return false;
    }

    CreatureInfo const* cinfo = normalInfo;

    SetEntry(Entry); // normal entry always
    m_creatureInfo = cinfo; // map mode related always

    SetObjectScale(cinfo->Scale);

    // equal to player Race field, but creature does not have race
    SetByteValue(UNIT_FIELD_BYTES_0, 0, 0);

    // known valid are: CLASS_WARRIOR,CLASS_PALADIN,CLASS_ROGUE,CLASS_MAGE
    SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->UnitClass));

    uint32 display_id = ChooseDisplayId(GetCreatureInfo(), data, eventData);
    if (!display_id) // Cancel load if no display id
    {
    sLog.outErrorDb("Creature (Entry: %u) has no model defined in table `creature_template`, can't load.", Entry);
    return false;
    }

    CreatureModelInfo const* minfo = sObjectMgr.GetCreatureModelRandomGender(display_id);
    if (!minfo) // Cancel load if no model defined
    {
    sLog.outErrorDb("Creature (Entry: %u) has no model info defined in table `creature_model_info`, can't load.", Entry);
    return false;
    }

    display_id = minfo->modelid; // it can be different (for another gender)

    SetNativeDisplayId(display_id);

    // special case for totems (model for team==HORDE is stored in creature_template as the default)
    if (team == ALLIANCE && cinfo->CreatureType == CREATURE_TYPE_TOTEM)
    {
    uint32 modelid_tmp = sObjectMgr.GetCreatureModelOtherTeamModel(display_id);
    display_id = modelid_tmp ? modelid_tmp : display_id;
    }

    // normally the same as native, see above for the exeption
    SetDisplayId(display_id);

    SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);

    // set PowerType based on unit class
    switch (cinfo->UnitClass)
    {
    case CLASS_WARRIOR:
    SetPowerType(POWER_RAGE);
    break;
    case CLASS_PALADIN:
    case CLASS_MAGE:
    SetPowerType(POWER_MANA);
    break;
    case CLASS_ROGUE:
    SetPowerType(POWER_ENERGY);
    break;
    default:
    sLog.outErrorDb("Creature (Entry: %u) has unhandled unit class. Power type will not be set!", Entry);
    break;
    }

    // Load creature equipment
    if (eventData && eventData->equipment_id)
    {
    LoadEquipment(eventData->equipment_id); // use event equipment if any for active event
    }
    else if (!data || data->equipmentId == 0)
    {
    // use default from the template
    LoadEquipment(cinfo->EquipmentTemplateId);
    }
    else if (data && data->equipmentId != -1)
    {
    // override, -1 means no equipment
    LoadEquipment(data->equipmentId);
    }

    SetName(normalInfo->Name); // at normal entry always

    SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);

    // update speed for the new CreatureInfo base speed mods
    UpdateSpeed(MOVE_WALK, false);
    UpdateSpeed(MOVE_RUN, false);

    SetLevitate(cinfo->InhabitType & INHABIT_AIR);

    // checked at loading
    m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);

    return true;
    }

    void Creature::Despawn()
    {
    SetCorpseDelay(0);
    SetRespawnDelay(-1);
    ForcedDespawn();
    }

    void Creature::MovementHaltFaceTo(Player* pPlayer)
    {
    InterruptMoving(false);
    SetFacingToObject(pPlayer);
    SetSheath(SHEATH_STATE_UNARMED);
    Sleep(100);
    }

    void Creature::FaceBack(float curface, uint16 waittime)
    {
    Sleep(waittime);
    SetSheath(SHEATH_STATE_MELEE);
    SetFacingTo(curface);
    }


    Creature.h file

    class MANGOS_DLL_SPEC Creature : public Unit
    {
    CreatureAI* i_AI;

    public:

    /* Loot Variables */
    bool hasBeenLootedOnce;
    uint32 assignedLooter;

    explicit Creature(CreatureSubtype subtype = CREATURE_SUBTYPE_GENERIC);
    virtual ~Creature();

    void AddToWorld() override;
    void RemoveFromWorld() override;

    bool Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, Team team = TEAM_NONE, const CreatureData* data = NULL, GameEventCreatureData const* eventData = NULL);
    bool LoadCreatureAddon(bool reload);
    void SelectLevel(const CreatureInfo* cinfo, float percentHealth = 100.0f, float percentMana = 100.0f);
    void LoadEquipment(uint32 equip_entry, bool force = false);

    bool HasStaticDBSpawnData() const; // listed in `creature` table and have fixed in DB guid

    char const* GetSubName() const { return GetCreatureInfo()->SubName; }

    void Update(uint32 update_diff, uint32 time) override; // overwrite Unit::Update

    virtual void RegenerateAll(uint32 update_diff);
    uint32 GetEquipmentId() const { return m_equipmentId; }

    CreatureSubtype GetSubtype() const { return m_subtype; }
    bool IsPet() const { return m_subtype == CREATURE_SUBTYPE_PET; }
    bool IsTotem() const { return m_subtype == CREATURE_SUBTYPE_TOTEM; }
    bool IsTemporarySummon() const { return m_subtype == CREATURE_SUBTYPE_TEMPORARY_SUMMON; }

    bool IsCorpse() const { return GetDeathState() == CORPSE; }
    bool IsDespawned() const { return GetDeathState() == DEAD; }
    void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
    uint32 GetCorpseDelay() const { return m_corpseDelay; }
    bool IsRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
    bool IsCivilian() const { return GetCreatureInfo()->civilian; }
    bool IsGuard() const { return GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_GUARD; }

    bool CanWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; }
    virtual bool CanSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; }
    bool CanFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; }

    bool IsTrainerOf(Player* player, bool msg) const;
    bool CanInteractWithBattleMaster(Player* player, bool msg) const;
    bool CanTrainAndResetTalentsOf(Player* pPlayer) const;

    bool IsOutOfThreatArea(Unit* pVictim) const;
    void FillGuidsListFromThreatList(GuidVector& guids, uint32 maxamount = 0);

    bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf) override;
    bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const override;

    bool IsElite() const
    {
    if (IsPet())
    { return false; }

    uint32 rank = GetCreatureInfo()->Rank;
    return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
    }

    bool IsWorldBoss() const
    {
    if (IsPet())
    { return false; }

    return GetCreatureInfo()->Rank == CREATURE_ELITE_WORLDBOSS;
    }

    uint32 GetLevelForTarget(Unit const* target) const override; // overwrite Unit::GetLevelForTarget for boss level support

    bool IsInEvadeMode() const;

    bool AIM_Initialize();

    CreatureAI* AI() { return i_AI; }

    void SetWalk(bool enable, bool asDefault = true);
    void SetLevitate(bool enable);
    void SetRoot(bool enable) override;
    void SetWaterWalk(bool enable) override;

    uint32 GetShieldBlockValue() const override // dunno mob block value
    {
    return (getLevel() / 2 + uint32(GetStat(STAT_STRENGTH) / 20));
    }

    SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; }
    void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = GetSchoolMask(school); }

    void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time);
    void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time);
    void AddCreatureSpellCooldown(uint32 spellid);
    bool HasSpellCooldown(uint32 spell_id) const;
    bool HasCategoryCooldown(uint32 spell_id) const;
    uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const;

    bool HasSpell(uint32 spellID) const override;

    void Despawn();
    void MovementHaltFaceTo(Player* pPlayer);
    void FaceBack(float curface, uint16 waittime);


    User Feedback

    Recommended Comments

    [quote=Arkadus]Yep your right there is an error, i had to make this code on the fly using notepad i obviously rushed it too quickly sorting it out now.[/quote]

    [quote=Arkadus]Should be good now. My fault.[/quote]

    Ah, excellent, thanks :D

    I'll deal with this as soon as I can :)

    Link to comment
    Share on other sites

    The instance reset times are well know. Instead of an unsafe using ForcedDespawn() right at the creature creation moment and implanting a thrash into many instance scripts, one should correct boss respawn times creature.spawntimesecs in the way that these values were not less that the corresponding instance reset times.

    Also, two helper functions related to moving are misplaced at least. These helpers are supposed to be used in SD2 scripts, therefore they should be defined in either of ScriptedAI, CreatureAI, UnitAI class. If these are needed by Eluna too, it can implement them either by own LUA scripts or at the interface level.

    Try do not mangle the Creature class as long as it's possible plz :)

    Link to comment
    Share on other sites



    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use