/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | * * -----------------------------------------------------------| \\._.// * * SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) * * -----------------------------------------------------------| ).:.( * * SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} * * -----------------------------------------------------------| / ' ' \ * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~* * Scryn, Swordbearer, Rennard, Tricops, and Gorog. | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Skills Interface file * ****************************************************************************/ #ifndef SKILL_H #define SKILL_H #define deCurrentSkillVersion "1000" #ifdef SMAUGSERVER_CPP char *SpellSaveNames [6] = { "none", "poison_death", "wands", "para_petri", "breath", "spell_staff" }; char *SpellSaveEffectNames [8] = { "none", "negate", "eightdam", "quarterdam", "halfdam", "3qtrdam", "reflect", "absorb" }; #endif extern char *SpellSaveNames [6]; extern char *SpellSaveEffectNames [8]; #define ASSIGN_GSN(gsn, skill) \ do \ { \ if (((gsn) = SkillTable.Lookup((skill))) == -1 ) \ fprintf(stderr, "ASSIGN_GSN: Skill %s not found.\n", \ (skill) ); \ } while(0) #define SET_SDAM(skill, val) ((skill)->SetInfo (((skill)->GetInfo() & SDAM_MASK) + ((val) & 7))) #define SET_SACT(skill, val) ((skill)->SetInfo (((skill)->GetInfo() & SACT_MASK) + (((val) & 7) << 3))) #define SET_SCLA(skill, val) ((skill)->SetInfo (((skill)->GetInfo() & SCLA_MASK) + (((val) & 7) << 6))) #define SET_SPOW(skill, val) ((skill)->SetInfo (((skill)->GetInfo() & SPOW_MASK) + (((val) & 3) << 9))) /* RIS by gsn lookups. -- Altrag. Will need to add some || stuff for spells that need a special GSN. */ #define IS_FIRE(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsFireSpell ()) #define IS_COLD(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsColdSpell ()) #define IS_ACID(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsAcidSpell ()) #define IS_ELECTRICITY(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsElectricitySpell ()) #define IS_ENERGY(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsEnergySpell ()) #define IS_DRAIN(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsDrainSpell ()) #define IS_POISON(dt) (SkillTable.IsValid(dt) && \ SkillTable.GetSkill (dt)->IsPoisonSpell ()) // Skills include spells as a particular case. class CSkill { public: CSkill () { ClearAddrRange (&m_pName, &m_UseRec, sizeof (m_UseRec)); } ~CSkill (); void Read (FILE* fp); void Write (FILE* fp); short GetType () { return m_Type; } void SetType (short t) { m_Type = t; } char *GetName () { return m_pName; } BOOL HasName () { return m_pName && *m_pName; } void SetName (char* n) { m_pName = n; } int GetFlags () { return m_Flags; } void SetFlags (int f) { m_Flags = f; } int GetValue () { return m_Value; } void SetValue (int v) { m_Value = v; } short GetTarget () { return m_Target; } void SetTarget (short t) { m_Target = t; } int GetInfo () { return m_Info; } void SetInfo (int i) { m_Info = i; } short GetMinimumPosition () { return m_MinPos; } void SetMinimumPosition (short p) { m_MinPos = p; } char GetSaves () { return m_Saves; } void SetSaves (char s) { m_Saves = s; } short GetSlot () { return m_Slot; } void SetSlot (short s) { m_Slot = s; } short GetMinMana () { return m_MinMana; } void SetMinMana (int m) { m_MinMana = m; } short GetRange () { return m_Range; } void SetRange (short r) { m_Range = r; } short GetBeats () { return m_Beats; } void SetBeats (short b) { m_Beats = b; } short GetGuild () { return m_Guild; } void SetGuild (int g) { m_Guild = g; } short GetMinLevel () { return m_MinLevel; } void SetMinLevel (int lev) { m_MinLevel = lev; } DO_FUN *GetSkillFunction () { return m_SkillFun; } void SetSkillFunction (DO_FUN* f) { m_SkillFun = f; } SPELL_FUN *GetSpellFunction () { return m_SpellFun; } void SetSpellFunction (SPELL_FUN* f) { m_SpellFun = f; } BOOL ValidDamageMsg () { return m_pDamMsg && m_pDamMsg[0] != '\0'; } char *GetDamageMsg () { return m_pDamMsg; } void SetDamageMsg (char* m) { m_pDamMsg = m; } BOOL ValidOffMsg () { return m_OffMsg && m_OffMsg[0] != '\0'; } char *GetOffMsg () { return m_OffMsg; } void SetOffMsg (char* m) { m_OffMsg = m; } char *GetHitCharMsg () { return m_HitChar; } void SetHitCharMsg (char* m) { m_HitChar = m; } BOOL ValidHitCharMsg () { return m_HitChar && m_HitChar[0] != '\0'; } char *GetHitVictMsg () { return m_HitVict; } void SetHitVictMsg (char* m) { m_HitVict = m; } BOOL ValidHitVictMsg () { return m_HitVict && m_HitVict[0] != '\0'; } char *GetHitRoomMsg () { return m_HitRoom; } void SetHitRoomMsg (char* m) { m_HitRoom = m; } BOOL ValidHitRoomMsg () { return m_HitRoom && m_HitRoom[0] != '\0'; } char *GetHitDest () { return m_HitDest; } void SetHitDest (char* d) { m_HitDest = d; } BOOL ValidHitDest () { return m_HitDest && m_HitDest[0] != '\0'; } char *GetMissCharMsg () { return m_MissChar; } void SetMissCharMsg (char* m) { m_MissChar = m; } BOOL ValidMissCharMsg () { return m_MissChar && m_MissChar[0] != '\0'; } char *GetMissVictMsg () { return m_MissVict; } void SetMissVictMsg (char* m) { m_MissVict = m; } BOOL ValidMissVictMsg () { return m_MissVict && m_MissVict[0] != '\0'; } char *GetMissRoomMsg () { return m_MissRoom; } void SetMissRoomMsg (char* m) { m_MissRoom = m; } BOOL ValidMissRoomMsg () { return m_MissRoom && m_MissRoom[0] != '\0'; } char *GetDieCharMsg () { return m_DieChar; } void SetDieCharMsg (char* m) { m_DieChar = m; } BOOL ValidDieCharMsg () { return m_DieChar && m_DieChar[0] != '\0'; } char *GetDieVictMsg () { return m_DieVict; } void SetDieVictMsg (char* m) { m_DieVict = m; } BOOL ValidDieVictMsg () { return m_DieVict && m_DieVict[0] != '\0'; } char *GetDieRoomMsg () { return m_DieRoom; } void SetDieRoomMsg (char* m) { m_DieRoom = m; } BOOL ValidDieRoomMsg () { return m_DieRoom && m_DieRoom[0] != '\0'; } char *GetImmuneCharMsg () { return m_ImmChar; } void SetImmuneCharMsg (char* m) { m_ImmChar = m; } BOOL ValidImmuneCharMsg () { return m_ImmChar && m_ImmChar[0] != '\0'; } char *GetImmuneVictMsg () { return m_ImmVict; } void SetImmuneVictMsg (char* m) { m_ImmVict = m; } BOOL ValidImmuneVictMsg () { return m_ImmVict && m_ImmVict[0] != '\0'; } char *GetImmuneRoomMsg () { return m_ImmRoom; } void SetImmuneRoomMsg (char* m) { m_ImmRoom = m; } BOOL ValidImmuneRoomMsg () { return m_ImmRoom && m_ImmRoom[0] != '\0'; } char *GetDiceRoll () { return m_pDice; } void SetDiceRoll (char* d) { m_pDice = d; } char GetDifficulty () { return m_Difficulty; } void SetDifficulty (char d) { m_Difficulty = d; } char GetParticipants () { return m_Participants; } void SetParticipants (char p) { m_Participants = p; } char *GetComponents () { return m_pComponents; } void SetComponents (char* c) { m_pComponents = c; } char *GetTeachers () { return m_pTeachers; } BOOL HasTeachers () { return m_pTeachers && *m_pTeachers; } void SetTeachers (char* t) { m_pTeachers = t; } CSmaugAffect *GetAffects () { return m_pAffects; } void SetAffects (CSmaugAffect* aff) { m_pAffects = aff; } timerset GetUseRec () { return m_UseRec; } short GetClassLevel (int cl) { return m_ClassLevel [cl]; } void SetClassLevel (int cl, int lev) { m_ClassLevel.SetAtGrow (cl, lev); } short GetClassAdept (int cl) { return m_ClassAdept [cl]; } void SetClassAdept (int cl, int adp) { m_ClassAdept.SetAtGrow (cl, adp); } short GetRaceLevel (int r) { return r < m_RaceLevel.GetSize () ? m_RaceLevel [r] : 0; } void SetRaceLevel (int r, int lev) { m_RaceLevel.SetAtGrow (r, lev); } short GetRaceAdept (int r) { return r < m_RaceAdept.GetSize () ? m_RaceAdept [r] : 0; } void SetRaceAdept (int r, int adp) { m_RaceAdept.SetAtGrow (r, adp); } #define SSAV_MASK (UINT_MAX & ~(BV11 | BV12 | BV13)) int GetSaveEffect () { return (m_Info >> 11) & 7; } void SetSaveEffect (int v) { m_Info = (m_Info & SSAV_MASK) + ((v & 7) << 11); } const char *GetSaveName () { ASSERT (m_Saves < DIM (SpellSaveNames)); return SpellSaveNames [m_Saves]; } const char *GetSaveEffectName () { return SpellSaveEffectNames [(m_Info >> 11) & 7]; } BOOL HasSpell (int bit) { return (m_Flags & bit) != 0; } BOOL IsAreaSpell () { return (m_Flags & SF_AREA) != 0; } BOOL IsObjectSpell () { return (m_Flags & SF_OBJECT) != 0; } BOOL IsCharacterSpell () { return (m_Flags & SF_CHARACTER) != 0; } BOOL IsNoSelf () { return (m_Flags & SF_NOSELF) != 0; } BOOL IsSecret () { return (m_Flags & SF_SECRETSKILL) != 0; } BOOL IsNoScribe () { return (m_Flags & SF_NOSCRIBE) != 0; } BOOL IsNoBrew () { return (m_Flags & SF_NOBREW) != 0; } BOOL IsPkSensitive () { return (m_Flags & SF_PKSENSITIVE) != 0; } BOOL IsAccumulative () { return (m_Flags & SF_ACCUMULATIVE) != 0; } BOOL IsRecastable () { return (m_Flags & SF_RECASTABLE) != 0; } BOOL IsStopOnFail () { return (m_Flags & SF_STOPONFAIL) != 0; } BOOL IsGroupSpell () { return (m_Flags & SF_GROUPSPELL) != 0; } BOOL IsWaterSpell () { return (m_Flags & SF_WATER) != 0; } BOOL IsDistantSpell () { return (m_Flags & SF_DISTANT) != 0; } BOOL IsNoFightSpell () { return (m_Flags & SF_NOFIGHT) != 0; } //#define SPELL_ACTION(skill) ( ((skill)->info >> 3) & 7 ) int GetSpellAction () { return (m_Info >> 3) & 7; } BOOL IsDestroySpell () { return ((m_Info >> 3) & 7) == SA_DESTROY; } BOOL IsCreateSpell () { return ((m_Info >> 3) & 7) == SA_CREATE; } //#define SPELL_DAMAGE(skill) ( ((skill)->info ) & 7 ) int GetSpellDamage () { return m_Info & 7; } BOOL IsFireSpell () { return (m_Info & 7) == SD_FIRE; } BOOL IsPoisonSpell () { return (m_Info & 7) == SD_POISON; } BOOL IsColdSpell () { return (m_Info & 7) == SD_COLD; } BOOL IsAcidSpell () { return (m_Info & 7) == SD_ACID; } BOOL IsElectricitySpell () { return (m_Info & 7) == SD_ELECTRICITY; } BOOL IsEnergySpell () { return (m_Info & 7) == SD_ENERGY; } BOOL IsDrainSpell () { return (m_Info & 7) == SD_DRAIN; } //#define SPELL_CLASS(skill) ( ((skill)->info >> 6) & 7 ) int GetSpellClass () { return (m_Info >> 6) & 7; } BOOL IsLifeSpell () { return ((m_Info >> 6) & 7) == SC_LIFE; } BOOL IsDeathSpell () { return ((m_Info >> 6) & 7) == SC_DEATH; } BOOL IsIllusionSpell () { return ((m_Info >> 6) & 7) == SC_ILLUSION; } BOOL HasNoSpellClass () { return ((m_Info >> 6) & 7) == SC_NONE; } //#define SPELL_POWER(skill) ( ((skill)->info >> 9) & 3 ) int GetSpellPower () { return (m_Info >> 9) & 3; } friend class CSkillTable; protected: char *m_pName; // Name of skill SPELL_FUN *m_SpellFun; // Spell pointer (for spells) DO_FUN *m_SkillFun; // Skill pointer (for skills) short m_Target; // Legal targets short m_MinPos; // Position for caster / user short *pgsn; // Pointer to associated gsn short m_Slot; // Slot for #OBJECT loading short m_MinMana; // Minimum mana used short m_Beats; // Waiting time after use short m_Range; // for projectiles char *m_pDamMsg; // Damage message char *m_OffMsg; // Wear off message short m_Guild; // Which guild the skill belongs to short m_MinLevel; // Minimum level to be able to cast short m_Type; // Spell/Skill/Weapon/Tongue int m_Info; int m_Flags; // extra stuff char *m_HitChar; // Success message to caster char *m_HitVict; // Success message to victim char *m_HitRoom; // Success message to room char *m_HitDest; char *m_MissChar; // Failure message to caster char *m_MissVict; // Failure message to victim char *m_MissRoom; // Failure message to room char *m_DieChar; // Victim death msg to caster char *m_DieVict; // Victim death msg to victim char *m_DieRoom; // Victim death msg to room char *m_ImmChar; // Victim immune msg to caster char *m_ImmVict; // Victim immune msg to victim char *m_ImmRoom; // Victim immune msg to room char *m_pDice; // Dice roll int m_Value; // Misc value char m_Saves; // What saving spell applies char m_Difficulty; // Difficulty of casting/learning char *m_pComponents; // Spell components, if any char *m_pTeachers; // Skill requires a special teacher char m_Participants; // # of required participants CSmaugAffect *m_pAffects; // Spell affects, if any timerset m_UseRec; // Usage record CWordArray m_ClassLevel; // Level needed by class CWordArray m_ClassAdept; // Max attainable % in this skill CWordArray m_RaceLevel; // Level needed by race CWordArray m_RaceAdept; // Max attainable % for this race }; class CSkillTable { public: CSkillTable (int max) { m_Max = max; m_Top = 0; m_sk = new CSkill* [max]; ZeroMemory (m_sk, sizeof (m_sk) * max); } ~CSkillTable () { delete [] m_sk; } CString GetCurrentVersion () { return deCurrentSkillVersion; } void RemoveAll (); BOOL IsValid (int sn) { return sn >= 0 && sn < m_Max && m_sk [sn] && m_sk [sn]->m_pName; } BOOL Read (FILE* fp); void Add (CSkill* skill); void Write (FILE* fp, int sn) { m_sk [sn]->Write (fp); } void Sort (); int Lookup (const char *name); int Bsearch (const char *name, int first, int top); int BsearchExact (const char *name, int first, int top); int ChBsearch (CCharacter *ch, const char *name, int first, int top); CSkill *GetSkill (int sn) { return IsValid (sn) ? m_sk [sn] : NULL; } CSkill *GetValidSkill (int sn); CSkill *Find (const char *name) { return GetSkill (Lookup (name)); } int GetCount () { return m_Top; } char *GetName (int sn) { return m_sk [sn]->m_pName; } BOOL HasName (int sn) { return m_sk [sn]->HasName (); } short GetSlot (int sn) { return m_sk [sn]->m_Slot; } short GetType (int sn) { return m_sk [sn]->m_Type; } short GetMinMana (int sn) { return m_sk [sn]->m_MinMana; } short GetClassLevel (int sn, int cl) { return m_sk [sn]->GetClassLevel (cl); } short GetClassAdept (int sn, int cl) { return m_sk [sn]->GetClassAdept (cl); } short GetTarget (int sn) { return m_sk [sn]->m_Target; } short GetMinimumPosition (int sn) { return m_sk [sn]->m_MinPos; } short GetBeats (int sn) { return m_sk [sn]->m_Beats; } short GetGuild (int sn) { return m_sk [sn]->m_Guild; } char GetDifficulty (int sn) { return m_sk [sn]->m_Difficulty; } timerset GetUseRec (int sn) { return m_sk [sn]->GetUseRec (); } void SetClassLevel (int sn, int cl, int lev) { m_sk [sn]->SetClassLevel(cl, lev); } void SetClassAdept (int sn, int cl, int adp) { m_sk [sn]->SetClassAdept(cl, adp); } char *GetTeachers (int sn) { return m_sk [sn]->m_pTeachers; } DO_FUN *GetSkillFunction (int sn) { return m_sk [sn]->m_SkillFun; } SPELL_FUN *GetSpellFunction (int sn) { return m_sk [sn]->m_SpellFun; } int GetSaveEffectFromName (const char* name); private: int m_Top; // top Skill loaded int m_Max; CSkill **m_sk; }; #ifdef SMAUGSERVER_CPP CSkillTable SkillTable (MAX_SKILL); CSkillTable HerbTable (MAX_HERB); #else extern CSkillTable SkillTable; extern CSkillTable HerbTable; #endif #endif // SKILL_H