mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-02 00:06:36 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into web_interface
# Conflicts: # zone/attack.cpp # zone/entity.cpp # zone/net.cpp # zone/worldserver.cpp # zone/zone.cpp
This commit is contained in:
@@ -2,11 +2,14 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(zone_sources
|
||||
aa.cpp
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
attack.cpp
|
||||
beacon.cpp
|
||||
bonuses.cpp
|
||||
bot.cpp
|
||||
bot_command.cpp
|
||||
bot_database.cpp
|
||||
botspellsai.cpp
|
||||
client.cpp
|
||||
client_mods.cpp
|
||||
@@ -20,6 +23,7 @@ SET(zone_sources
|
||||
embparser_api.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
encounter.cpp
|
||||
entity.cpp
|
||||
exp.cpp
|
||||
fearpath.cpp
|
||||
@@ -28,6 +32,7 @@ SET(zone_sources
|
||||
guild.cpp
|
||||
guild_mgr.cpp
|
||||
hate_list.cpp
|
||||
heal_rotation.cpp
|
||||
horse.cpp
|
||||
inventory.cpp
|
||||
loottables.cpp
|
||||
@@ -35,6 +40,7 @@ SET(zone_sources
|
||||
lua_corpse.cpp
|
||||
lua_client.cpp
|
||||
lua_door.cpp
|
||||
lua_encounter.cpp
|
||||
lua_entity.cpp
|
||||
lua_entity_list.cpp
|
||||
lua_general.cpp
|
||||
@@ -126,9 +132,12 @@ SET(zone_sources
|
||||
|
||||
SET(zone_headers
|
||||
aa.h
|
||||
aa_ability.h
|
||||
basic_functions.h
|
||||
beacon.h
|
||||
bot.h
|
||||
bot_command.h
|
||||
bot_database.h
|
||||
bot_structs.h
|
||||
client.h
|
||||
client_packet.h
|
||||
@@ -139,6 +148,7 @@ SET(zone_headers
|
||||
embparser.h
|
||||
embperl.h
|
||||
embxs.h
|
||||
encounter.h
|
||||
entity.h
|
||||
errmsg.h
|
||||
event_codes.h
|
||||
@@ -146,10 +156,12 @@ SET(zone_headers
|
||||
groups.h
|
||||
guild_mgr.h
|
||||
hate_list.h
|
||||
heal_rotation.h
|
||||
horse.h
|
||||
lua_bit.h
|
||||
lua_client.h
|
||||
lua_corpse.h
|
||||
lua_encounter.h
|
||||
lua_entity.h
|
||||
lua_entity_list.h
|
||||
lua_general.h
|
||||
|
||||
+979
-1324
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,8 @@
|
||||
|
||||
#ifndef AA_H
|
||||
#define AA_H
|
||||
|
||||
struct AA_Ability;
|
||||
struct SendAA_Struct;
|
||||
|
||||
|
||||
#define MANA_BURN 664
|
||||
|
||||
#include <map>
|
||||
|
||||
#define MAX_SWARM_PETS 12 //this can change as long as you make more coords (swarm_pet_x/swarm_pet_y)
|
||||
|
||||
//this might be missing some, and some might not be used...
|
||||
typedef enum { //AA Targeting Constants
|
||||
aaTargetUser = 1,
|
||||
aaTargetCurrent = 2, //use current target
|
||||
aaTargetGroup = 3, //target group of user
|
||||
aaTargetCurrentGroup = 4, //target group of current target
|
||||
aaTargetPet = 5 //target the user's pet
|
||||
} aaTargetType;
|
||||
|
||||
|
||||
typedef enum {
|
||||
aaActionNone = 0,
|
||||
aaActionAETaunt = 1,
|
||||
@@ -42,21 +23,6 @@ typedef enum {
|
||||
aaActionFadingMemories = 16
|
||||
} aaNonspellAction;
|
||||
|
||||
//use these for AAs which dont cast spells, yet need effects
|
||||
//if this list grows beyond 32, more work is needed in *AAEffect
|
||||
typedef enum { //AA Effect IDs
|
||||
aaEffectMassGroupBuff = 1, //unused - Handled via spell effect.
|
||||
aaEffectRampage,
|
||||
aaEffectSharedHealth,
|
||||
aaEffectFlamingArrows,
|
||||
aaEffectFrostArrows,
|
||||
aaEffectWarcry,
|
||||
aaEffectLeechTouch,
|
||||
aaEffectProjectIllusion, // unused - Handled via spell effect
|
||||
_maxaaEffectType = 32
|
||||
} aaEffectType;
|
||||
|
||||
|
||||
enum { //leadership AA indexes
|
||||
groupAAMarkNPC = 0,
|
||||
groupAANPCHealth,
|
||||
@@ -133,571 +99,6 @@ static const uint8 LeadershipAACosts[_maxLeaderAA][MAX_LEADERSHIP_TIERS] = {
|
||||
{ 0, 0, 0, 0, 0, 0 }, //raidAA15
|
||||
};
|
||||
|
||||
/*
|
||||
typedef enum { //AA IDs
|
||||
aaNone = 0,
|
||||
aaInnateStrength = 2, //works
|
||||
aaInnateStamina = 7, //works
|
||||
aaInnateAgility = 12, //works
|
||||
//aaCompleteHeal = 13,/ //not implemented, but is in dbstr_us.txt
|
||||
aaInnateDexterity = 17, //works
|
||||
aaInnateIntelligence = 22, //works
|
||||
aaInnateWisdom = 27, //works
|
||||
aaInnateCharisma = 32, //works
|
||||
aaInnateFireProtection = 37, //works
|
||||
aaInnateColdProtection = 42, //works
|
||||
aaInnateMagicProtection = 47, //works
|
||||
aaInnatePoisonProtection = 52, //works
|
||||
aaInnateDiseaseProtection = 57, //works
|
||||
aaInnateRunSpeed = 62, //works
|
||||
aaInnateRegeneration = 65, //works
|
||||
aaInnateMetabolism = 68,
|
||||
aaInnateLungCapacity = 71, //handled by client
|
||||
aaFirstAid = 74, //untested
|
||||
aaHealingAdept = 77, //untested
|
||||
aaHealingGift = 80, //untested
|
||||
aaSpellCastingMastery = 83, //untested
|
||||
aaSpellCastingReinforcement = 86, //untested
|
||||
aaMentalClarity = 89,
|
||||
aaSpellCastingFury = 92, //untested
|
||||
aaChanellingFocus = 95,
|
||||
aaSpellCastingSubtlety = 98, //untested
|
||||
aaSpellCastingExpertise = 101, //untested
|
||||
aaSpellCastingDeftness = 104, //untested
|
||||
aaNaturalDurability = 107, //works
|
||||
aaNaturalHealing = 110, //untested
|
||||
aaCombatFury = 113, //untested
|
||||
aaFearResistance = 116, //untested
|
||||
aaFinishingBlow = 119, //untested
|
||||
aaCombatStability = 122,
|
||||
aaCombatAgility = 125,
|
||||
aaMassGroupBuff = 128, //untested
|
||||
aaDivineResurrection = 129, //DB
|
||||
aaInnateInvisToUndead = 130, //DB
|
||||
aaCelestialRegeneration = 131, //untested
|
||||
aaBestowDivineAura = 132, //DB
|
||||
aaTurnUndead = 133, //DB
|
||||
aaPurifySoul = 136, //DB
|
||||
aaQuickEvacuation = 137, //untested
|
||||
aaExodus = 140, //untested
|
||||
aaQuickDamage = 141, //untested
|
||||
aaEnhancedRoot = 144,
|
||||
aaDireCharm = 145, //untested
|
||||
aaCannibalization = 146, //DB
|
||||
aaQuickBuff = 147, //untested
|
||||
aaAlchemyMastery = 150,
|
||||
aaRabidBear = 153, //DB
|
||||
aaManaBurn = 154, //DB
|
||||
aaImprovedFamiliar = 155, //untested, implemented?
|
||||
aaNexusGate = 156, //DB
|
||||
aaUnknown54 = 157,
|
||||
aaPermanentIllusion = 158,
|
||||
aaJewelCraftMastery = 159,
|
||||
aaGatherMana = 162, //DB
|
||||
aaMendCompanion = 163, //DB
|
||||
aaQuickSummoning = 164, //untested
|
||||
aaFrenziedBurnout = 167, //DB
|
||||
aaElementalFormFire = 168, //DB
|
||||
aaElementalFormWater = 171, //DB
|
||||
aaElementalFormEarth = 174, //DB
|
||||
aaElementalFormAir = 177, //DB
|
||||
aaImprovedReclaimEnergy = 180, //untested
|
||||
aaTurnSummoned = 181, //DB
|
||||
aaElementalPact = 182, //DB
|
||||
aaLifeBurn = 183, //DB
|
||||
aaDeadMesmerization = 184, //DB
|
||||
aaFearstorm = 185, //DB
|
||||
aaFleshToBone = 186, //DB
|
||||
aaCallToCorpse = 187, //DB
|
||||
aaDivineStun = 188, //DB
|
||||
aaImprovedLayOnHands = 189,
|
||||
aaSlayUndead = 190,
|
||||
aaActOfValor = 193, //DB
|
||||
aaHolySteed = 194, //DB
|
||||
aaFearless = 195,
|
||||
aa2HandBash = 196, //works. handled by client?
|
||||
aaInnateCamouflage = 197, //DB
|
||||
aaAmbidexterity = 198, //untested
|
||||
aaArcheryMastery = 199, //untested
|
||||
aaFletchingMastery = 202, //removed from db?
|
||||
aaEndlessQuiver = 205, //untested
|
||||
aaUnholySteed = 206, //DB
|
||||
aaImprovedHarmTouch = 207, //untested
|
||||
aaLeechTouch = 208, //DB
|
||||
aaDeathPeace = 209,
|
||||
aaSoulAbrasion = 210, //untested
|
||||
aaInstrumentMastery = 213, //untested
|
||||
aaUnknown91 = 216, //not used
|
||||
aaUnknown92 = 219, //not used
|
||||
aaUnknown93 = 222, //not used
|
||||
aaJamFest = 225,
|
||||
aaUnknown95 = 228,
|
||||
aaSonicCall = 229,
|
||||
aaCriticalMend = 230, //untested
|
||||
aaPurifyBody = 233, //DB
|
||||
aaChainCombo = 234,
|
||||
aaRapidFeign = 237, //works
|
||||
aaReturnKick = 240,
|
||||
aaEscape = 243, //DB
|
||||
aaPoisonMastery = 244,
|
||||
aaDoubleRiposte = 247, //untested
|
||||
aaQuickHide = 250,
|
||||
aaQuickThrow = 253, //corrected from dbstr_us.txt
|
||||
aaPurgePoison = 254, //DB
|
||||
aaFlurry = 255, //untested
|
||||
aaRampage = 258, //untested
|
||||
aaAreaTaunt = 259, //untested
|
||||
aaWarcry = 260, //DB
|
||||
aaBandageWound = 263, //untested
|
||||
aaSpellCastingReinforcementMastery = 266, //untested
|
||||
aaSpellCastingFuryMastery = 267, //untested
|
||||
aaExtendedNotes = 270, //untested
|
||||
aaDragonPunch = 273,
|
||||
aaStrongRoot = 274, //DB
|
||||
aaSingingMastery = 275, //untested
|
||||
aaBodyAndMindRejuvenation = 278, //added
|
||||
aaPhysicalEnhancement = 279, //untested
|
||||
aaAdvTrapNegotiation = 280, //untested
|
||||
aaAcrobatics = 283, //untested
|
||||
aaScribbleNotes = 286,
|
||||
aaChaoticStab = 287, //untested
|
||||
aaPetDiscipline = 288, //added
|
||||
aaHobbleofSpirits = 289, //DB
|
||||
aaFrenzyofSpirit = 290, //DB
|
||||
aaParagonofSpirit = 291, //DB
|
||||
aaAdvancedInnateStrength = 292, //works
|
||||
aaAdvancedInnateStamina = 302, //works
|
||||
aaAdvancedInnateAgility = 312, //works
|
||||
aaAdvancedInnateDexterity = 322, //works
|
||||
aaAdvancedInnateIntelligence = 332, //works
|
||||
aaAdvancedInnateWisdom = 342, //works
|
||||
aaAdvancedInnateCharisma = 352, //works
|
||||
aaWardingofSolusek = 362, //works
|
||||
aaBlessingofEci = 372, //works
|
||||
aaMarrsProtection = 382, //works
|
||||
aaShroudofTheFaceless = 392, //works
|
||||
aaBertoxxulousGift = 402, //works
|
||||
aaNewTanaanCraftingMastery = 412,
|
||||
aaPlanarPower = 418, //untested
|
||||
aaPlanarDurability = 423, //added
|
||||
aaInnateEnlightenment = 426, //added
|
||||
aaAdvancedSpellCastingMastery = 431,//untested
|
||||
aaAdvancedHealingAdept = 434, //untested
|
||||
aaAdvancedHealingGift = 437, //untested
|
||||
aaCoupdeGrace = 440, //added
|
||||
aaFuryoftheAges = 443, //added
|
||||
aaMasteryofthePast = 446, //untested
|
||||
aaLightningReflexes = 449, //added
|
||||
aaInnateDefense = 454, //added
|
||||
aaRadiantCure = 459, //DB
|
||||
aaHastenedDivinity = 462, //DB
|
||||
aaHastenedTurning = 465, //DB
|
||||
aaHastenedPurificationofSoul = 468, //DB
|
||||
aaHastenedGathering = 471, //DB
|
||||
aaHastenedRabidity = 474, //DB
|
||||
aaHastenedExodus = 477, //DB
|
||||
aaHastenedRoot = 480, //DB
|
||||
aaHastenedMending = 483, //DB
|
||||
aaHastenedBanishment = 486, //DB
|
||||
aaHastenedInstigation = 489, //DB, maybe
|
||||
aaFuriousRampage = 492, //DB
|
||||
aaHastenedPurificationoftheBody = 495,//DB
|
||||
aaHastyExit = 498, //DB
|
||||
aaHastenedPurification = 501, //DB
|
||||
aaFlashofSteel = 504,
|
||||
aaDivineArbitration = 507, //DB
|
||||
aaWrathoftheWild = 510, //DB
|
||||
aaVirulentParalysis = 513, //DB
|
||||
aaHarvestofDruzzil = 516, //DB
|
||||
aaEldritchRune = 517, //DB
|
||||
aaServantofRo = 520, //DB
|
||||
aaWaketheDead = 523, //DB
|
||||
aaSuspendedMinion = 526, //untested
|
||||
aaSpiritCall = 528, //DB
|
||||
aaCelestialRenewal = 531, //DB
|
||||
aaAllegiantFamiliar = 533,
|
||||
aaHandofPiety = 534, //DB
|
||||
aaMithanielsBinding = 537, //untested
|
||||
aaMendingoftheTranquil = 539,
|
||||
aaRagingFlurry = 542,
|
||||
aaGuardianoftheForest = 545, //DB
|
||||
aaSpiritoftheWood = 548, //DB
|
||||
aaBestialFrenzy = 551, //untested
|
||||
aaHarmoniousAttack = 556, //untested
|
||||
aaKnightsAdvantage = 561,
|
||||
aaFerocity = 564,
|
||||
aaViscidRoots = 567,
|
||||
aaSionachiesCrescendo = 568, //untested
|
||||
aaAyonaesTutelage = 571,
|
||||
aaFeignedMinion = 574,
|
||||
aaUnfailingDivinity = 577,
|
||||
aaAnimationEmpathy = 580, // Implemented
|
||||
aaRushtoJudgement = 583,
|
||||
aaLivingShield = 586,
|
||||
aaConsumptionoftheSoul = 589, //untested
|
||||
aaBoastfulBellow = 592, //DB
|
||||
aaFervrentBlessing = 593, //untested
|
||||
aaTouchoftheWicked = 596, //untested
|
||||
aaPunishingBlade = 599,
|
||||
aaSpeedoftheKnight = 602,
|
||||
aaShroudofStealth = 605,
|
||||
aaNimbleEvasion = 606,
|
||||
aaTechniqueofMasterWu = 611,
|
||||
aaHostoftheElements = 616, //DB
|
||||
aaCallofXuzl = 619, //DB
|
||||
aaHastenedStealth = 622,
|
||||
aaIngenuity = 625,
|
||||
aaFleetofFoot = 628,
|
||||
aaFadingMemories = 630,
|
||||
aaTacticalMastery = 631,
|
||||
aaTheftofLife = 634,
|
||||
aaFuryofMagic = 637,
|
||||
aaFuryofMagicMastery2 = 640, //whats the difference?
|
||||
aaProjectIllusion = 643,
|
||||
aaHeadshot = 644, //added
|
||||
aaEntrap = 645, //DB
|
||||
aaUnholyTouch = 646, //untested
|
||||
aaTotalDomination = 649, // Implemented
|
||||
aaStalwartEndurance = 652, //implemented as bonus
|
||||
aaQuickSummoning2 = 655, //whats the difference?
|
||||
aaMentalClarity2 = 658, //whats the difference?
|
||||
aaInnateRegeneration2 = 661, //whats the difference?
|
||||
aaManaBurn2 = 664, //whats the difference?
|
||||
aaExtendedNotes2 = 665, //not implemented - later expansions replaced Extended Notes with this.
|
||||
aaSionachiesCrescendo2 = 668, //not implemented - later expansions replaced Sionachies Crescendo with this.
|
||||
aaImprovedReclaimEnergy2 = 671, //whats the difference? untetsed
|
||||
aaSwiftJourney = 672, //implemented as bonus
|
||||
aaConvalescence = 674, //added 9/26/08
|
||||
aaLastingBreath = 676, //handled by client
|
||||
aaPackrat = 678, //added 9/29/08
|
||||
aaHeightenedEndurance = 683,
|
||||
aaWeaponAffinity = 686, //implemented
|
||||
aaSecondaryForte = 691,
|
||||
aaPersistantCasting = 692,
|
||||
aaTuneofPursuance = 695,
|
||||
aaImprovedInstrumentMastery = 700,
|
||||
aaImprovedSingingMastery =701,
|
||||
aaExultantBellowing = 702,
|
||||
aaEchoofTaelosia = 707,
|
||||
aaInternalMetronome = 710, //In 2006 this AA was removed.
|
||||
aaPiousSupplication = 715,
|
||||
aaBeastialAlignment = 718, //untested
|
||||
aaWrathofXuzl = 721,
|
||||
aaFeralSwipe = 723, //DB?
|
||||
aaWardersFury = 724,
|
||||
aaWardersAlacrity = 729,
|
||||
aaPetAffinity = 734, // Implemented
|
||||
aaMasteryofthePast2 = 735, //whats the difference?
|
||||
aaSpellCastingSubtlety2 = 738, //whats the difference?
|
||||
aaTouchoftheDivine = 741,
|
||||
aaDivineAvatar = 746, //DB
|
||||
aaExquisiteBenediction = 749, //DB
|
||||
aaQuickenedCuring = 754,
|
||||
aaNaturesBoon = 757, //DB
|
||||
aaAdvancedTracking = 762,
|
||||
aaCriticalAffliction = 767,
|
||||
aaFuryofMagicMastery = 770, //whats the difference?
|
||||
aaDoppelganger = 773,
|
||||
aaEnchancedForgetfulness = 776,
|
||||
aaMesmerizationMastery = 781,
|
||||
aaQuickMassGroupBuff = 782,
|
||||
aaSharedHealth = 785,
|
||||
aaElementalFury = 790,
|
||||
aaElementalAlacrity = 795,
|
||||
aaElementalAgility = 800,
|
||||
aaElementalDurability = 803,
|
||||
aaSinisterStrikes = 806,
|
||||
aaStrikethrough = 807,
|
||||
aaStonewall = 810,
|
||||
aaRapidStrikes = 815,
|
||||
aaKickMastery = 820,
|
||||
aaHightenedAwareness = 823,
|
||||
aaDestructiveForce = 828, //DB
|
||||
aaSwarmofDecay = 831, //DB
|
||||
aaDeathsFury = 834,
|
||||
aaQuickeningofDeath = 839,
|
||||
aaAdvancedTheftofLife = 844,
|
||||
aaTripleBackstab = 846,
|
||||
aaHastenedPiety = 849,
|
||||
aaImmobilizingBash = 852,
|
||||
aaViciousSmash = 855,
|
||||
aaRadiantCure2 = 860, //whats the difference?
|
||||
aaPurification = 863,
|
||||
aaPrecisionofthePathfinder = 864,
|
||||
aaCoatofThistles = 867,
|
||||
aaFlamingArrows = 872, //untested
|
||||
aaFrostArrows = 875, //untested
|
||||
aaSeizedOpportunity = 878,
|
||||
aaTrapCircumvention = 881,
|
||||
aaImprovedHastyExit = 886,
|
||||
aaVirulentVenom = 888,
|
||||
aaImprovedConsumptionofSoul = 893,
|
||||
aaIntenseHatred = 895,
|
||||
aaAdvancedSpiritCall = 900,
|
||||
aaCalloftheAncients = 902, //DB
|
||||
aaSturdiness = 907,
|
||||
aaWarlordsTenacity = 912, //DB
|
||||
aaStrengthenedStrike = 915,
|
||||
aaExtendedShielding = 918,
|
||||
aaRosFlamingFamiliar = 921, //DB
|
||||
aaEcisIcyFamiliar = 922, //DB
|
||||
aaDruzzilsMysticalFamiliar = 923, //DB
|
||||
aaAdvancedFuryofMagicMastery = 924, //added 9/29/08
|
||||
aaWardofDestruction = 926, //DB
|
||||
aaFrenziedDevastation = 931, //DB
|
||||
aaCombatFury2 = 934, //whats the difference?
|
||||
aaCombatFury3 = 937, //whats the difference?
|
||||
aaCombatFury4 = 940, //whats the difference?
|
||||
aaFuryoftheAges2 = 943, //whats the difference?
|
||||
aaFuryoftheAges3 = 946, //whats the difference?
|
||||
aaFuryoftheAges4 = 949, //whats the difference?
|
||||
aaPlanarDurability2 = 952, //whats the difference?
|
||||
aaInnateEnlightenment2 = 955, //whats the difference?
|
||||
aaDireCharm2 = 960, //whats the difference?
|
||||
aaDireCharm3 = 961, //whats the difference?
|
||||
aaTouchoftheDivine2 = 962, //whats the difference?
|
||||
aaTouchofDecay = 967,
|
||||
aaCalloftheAncients2 = 970, //whats the difference?
|
||||
aaImprovedVision = 975,
|
||||
aaEternalBreath = 978, //handled by client
|
||||
aaBlacksmithingMastery = 979, //added 9/29/08
|
||||
aaBakingMastery = 982, //added 9/29/08
|
||||
aaBrewingMastery = 985, //added 9/29/08
|
||||
aaFletchingMastery2 = 988, //added 9/29/08
|
||||
aaPotteryMastery = 991, //added 9/29/08
|
||||
aaTailoringMastery = 994, //added 9/29/08
|
||||
aaSalvage = 997,
|
||||
aaOrigin = 1000, //spell
|
||||
aaChaoticPotential = 1001, //added
|
||||
aaDiscordantDefiance = 1006, //added 9/29/08
|
||||
aaTrialsofMataMuram = 1011,
|
||||
aaMysticalAttuning = 1021,
|
||||
aaDelayDeath = 1026,
|
||||
aaHealthyAura = 1031,
|
||||
aaFitness = 1036,
|
||||
aaVeteransWrath = 1041, //added 9/29/08
|
||||
aaVeteransWrath2 = 1044, //whats the difference?
|
||||
aaVeteransWrath3 = 1047, //whats the difference?
|
||||
aaVeteransWrath4 = 1050, //whats the difference?
|
||||
aaDeathblow = 1053,
|
||||
aaReflexiveMastery = 1061,
|
||||
aaDefensiveInstincts = 1066,
|
||||
aaMnemonicRetention = 1071, //Implemented
|
||||
aaExpansiveMind = 1072, //added 9/29/08
|
||||
aaSleightofHand = 1077,
|
||||
aaSleightofHand2 = 1080, //whats the difference?
|
||||
aaHealingAdeptMastery = 1083,
|
||||
aaHealingGiftMastery = 1086,
|
||||
aaArcaneTongues = 1089,
|
||||
aaMasterofDisguise = 1092,
|
||||
aaSlipperyAttacks = 1093,
|
||||
aaImprovedCriticalAffliction = 1099,
|
||||
aaFortifiedBellowing = 1102,
|
||||
aaFuryofMagic2 = 1107, //whats the difference?
|
||||
aaDanceofBlades = 1110,
|
||||
aaShieldofNotes = 1116,
|
||||
aaRoarofThunder = 1119,
|
||||
aaPersistentMinion = 1122,
|
||||
aaPerfectionofSpirit = 1123,
|
||||
aaReplentishCompanion = 1126,
|
||||
aaAdvancedPetDiscipline = 1129,
|
||||
aaThrowingMastery = 1131,
|
||||
aaBlurofAxes = 1134,
|
||||
aaHastenedWarCry = 1137,
|
||||
aaDeadAim = 1140,
|
||||
aaFrenziedDefense = 1143,
|
||||
aaTirelessSprint = 1146,
|
||||
aaDesperation = 1149,
|
||||
aaUntamedRage = 1150,
|
||||
aaEchoingCries = 1155,
|
||||
aaViciousFrenzy = 1158,
|
||||
aaCrazedOnslaught = 1163,
|
||||
aaOverwhelmingAttack = 1172,
|
||||
aaFuriousRage = 1175,
|
||||
aaBloodPact = 1178,
|
||||
aaShieldingResistance = 1181,
|
||||
aaHealingBoon = 1186,
|
||||
aaResplendentCure = 1189,
|
||||
aaCelestialHammer = 1192,
|
||||
aaDivineRetribution = 1195,
|
||||
aaCelestialRejuvination = 1203,
|
||||
aaFerventBenediction = 1206,
|
||||
aaSanctuary = 1209,
|
||||
aaDestructiveFury = 1210, //added 9/29/08
|
||||
aaDestructiveFury2 = 1213, //whats the difference?
|
||||
aaBoonoftheForest = 1222,
|
||||
aaSpiritoftheGrove = 1225,
|
||||
aaCalloftheWild = 1228,
|
||||
aaSecondaryRecall = 1229,
|
||||
aaNaturesBounty = 1230,
|
||||
aaStasis = 1233,
|
||||
aaColorShock = 1239,
|
||||
aaMindOverMatter = 1242,
|
||||
aaSoothingWords = 1245,
|
||||
aaElementalSwarm = 1248,
|
||||
aaHeartofFlames = 1251,
|
||||
aaHeartofVapor = 1252,
|
||||
aaHeartofIce = 1253,
|
||||
aaHeartofStone = 1254,
|
||||
aaImitateDeath = 1255,
|
||||
aaCripplingStrike = 1256,
|
||||
aaStunningKick = 1259,
|
||||
aaEyeGouge = 1262,
|
||||
aaIronKicks = 1265,
|
||||
aaStyleoftheMimic = 1268,
|
||||
aaDeathPeace2 = 1272, //whats the difference?
|
||||
aaArmyoftheDead = 1274,
|
||||
aaCelestialStun = 1277,
|
||||
aaHandofDevotion = 1278,
|
||||
aaSteadfastWill = 1284,
|
||||
aaShieldBlock = 1287,
|
||||
aaScoutsEfficiency = 1290,
|
||||
aaGuardianoftheGlade = 1293,
|
||||
aaTrackingMastery = 1296,
|
||||
aaFlurryofKnives = 1301,
|
||||
aaPrecision = 1304,
|
||||
aaNervesofSteel = 1307,
|
||||
aaTouchoftheCursed = 1313,
|
||||
aaSpiritualCorrosion = 1316,
|
||||
aaSoulThief = 1319,
|
||||
aaSpiritualChanneling = 1323,
|
||||
aaBoonoftheAncients = 1324,
|
||||
aaAncestralAid = 1327,
|
||||
aaResoluteDefiance = 1330,
|
||||
aaPresstheAttack = 1333,
|
||||
aaMindCrash = 1334,
|
||||
aaProlongedDestruction = 1337,
|
||||
aaRosGreaterFamiliar = 1340,
|
||||
aaEcisGreaterFamiliar = 1341,
|
||||
aaDruzzilsGreaterFamiliar = 1342,
|
||||
aaTeleportBind = 1343,
|
||||
aaDevotedFamiliar = 1344,
|
||||
aaAuspiceoftheHunter = 1345,
|
||||
aaSavageSpirit = 1348,
|
||||
aaPresstheAttack2 = 1351, //whats the difference?
|
||||
aaCripplingStrike2 = 1352, //whats the difference?
|
||||
aaStunningKick2 = 1353, //whats the difference?
|
||||
aaEyeGouge2 = 1358, //whats the difference?
|
||||
|
||||
//Dragons of Norrath
|
||||
//good info here: http://www.eqthieves.com/exp-don-progression.htm and here: http://everquest.allakhazam.com/db/guides.html?guide=811
|
||||
aaGiftoftheDarkReign = 1361, //from dbstr_us.txt
|
||||
aaTenacityoftheDarkReign = 1362, //from dbstr_us.txt
|
||||
aaEmbraceoftheDarkReign = 1363, //from dbstr_us.txt
|
||||
aaPoweroftheDarkReign = 1364, //from dbstr_us.txt
|
||||
aaFervoroftheDarkReign = 1365, //from dbstr_us.txt
|
||||
aaGiftoftheKeepers = 1366, //from dbstr_us.txt
|
||||
aaValoroftheKeepers = 1367, //from dbstr_us.txt
|
||||
aaEmbraceoftheKeepers = 1368, //from dbstr_us.txt
|
||||
aaPoweroftheKeepers = 1369, //from dbstr_us.txt
|
||||
aaSanctityoftheKeepers = 1370, //from dbstr_us.txt
|
||||
|
||||
//Veteran AAs
|
||||
aaLessonoftheDevoted = 1371, //from dbstr_us.txt
|
||||
aaInfusionoftheFaithful = 1372, //from dbstr_us.txt
|
||||
aaChaoticJester = 1373, //from dbstr_us.txt
|
||||
aaExpedientRecovery = 1374, //from dbstr_us.txt
|
||||
aaSteadfastServant = 1375, //from dbstr_us.txt
|
||||
aaStaunchRecovery = 1376, //from dbstr_us.txt
|
||||
aaIntensityoftheResolute = 1377, //from dbstr_us.txt
|
||||
|
||||
//Depths of Darkhollow
|
||||
|
||||
//the following 5 look to be used as flags for completion of the Blood Raids for access to the Demiplane of Blood
|
||||
//quest info here: http://everquest.allakhazam.com/db/quest.html?quest=3582
|
||||
//"You must also complete the five Blood Raids in any order: The Council of Nine, Emperor Draygun, Bloodeye, Matriarch Shyra, Sendaii, the Hive Queen"
|
||||
//"The AA's you receive are: Curse of Blood (1/5), Affliction of Blood (2/5), Torment of Blood (3/5), Temptation of Blood (4/5), Invitation of Blood (5/5)."
|
||||
aaCurseofBlood = 1378, //from dbstr_us.txt
|
||||
aaAfflictionofBlood = 1379, //from dbstr_us.txt
|
||||
aaTormentofBlood = 1380, //from dbstr_us.txt
|
||||
aaTemptationofBlood = 1381, //from dbstr_us.txt
|
||||
aaInvitationofBlood = 1382, //from dbstr_us.txt
|
||||
|
||||
aaTurnUndead2 = 1383, //from dbstr_us.txt, Class AA changed in DoD
|
||||
aaWrackUndead = 1386, //from dbstr_us.txt, PoP Class AA changed in DoD
|
||||
aaEradicateUndead = 1387, //from dbstr_us.txt
|
||||
aaInnateSeeInvis = 1388, //from dbstr_us.txt
|
||||
aaProlongedMortality = 1389, //from dbstr_us.txt
|
||||
aaPrecognition = 1394, //from dbstr_us.txt
|
||||
aaThickSkin = 1399, //from dbstr_us.txt
|
||||
aaSilentCasting = 1404, //from dbstr_us.txt
|
||||
aaSilentCasting2 = 1409, //from dbstr_us.txt
|
||||
aaHastenedMindCrash = 1414, //from dbstr_us.txt
|
||||
aaFieldDressing = 1417, //from dbstr_us.txt
|
||||
aaBandageWounds = 1420, //from dbstr_us.txt
|
||||
aaCascadingRage = 1425, //from dbstr_us.txt
|
||||
aaElementalFerocity = 1430, //from dbstr_us.txt
|
||||
aaGiftofMana = 1435, //from dbstr_us.txt
|
||||
aaRuneofShadows = 1440, //from dbstr_us.txt
|
||||
aaChannelingMastery = 1445, //from dbstr_us.txt
|
||||
aaConservation = 1453, //from dbstr_us.txt
|
||||
aaCryofBattle = 1458, //from dbstr_us.txt
|
||||
aaWardofPurity = 1459, //from dbstr_us.txt
|
||||
aaTurnSummoned2 = 1462, //from dbstr_us.txt
|
||||
aaWrackSummoned = 1465, //from dbstr_us.txt
|
||||
aaEradicateSummoned = 1466, //from dbstr_us.txt
|
||||
aaWardersSavagery = 1467, //from dbstr_us.txt
|
||||
aaShackleofSpirits = 1470, //from dbstr_us.txt
|
||||
aaHastenedThunder = 1471, //from dbstr_us.txt
|
||||
aaTranslocationalAnchor = 1474, //from dbstr_us.txt
|
||||
aaStealthyGetaway = 1477, //from dbstr_us.txt
|
||||
aaPyromancy = 1478, //from dbstr_us.txt
|
||||
aaMasteryofFury = 1483, //from dbstr_us.txt
|
||||
aaAbundantHealing = 1486, //from dbstr_us.txt
|
||||
aaGreaterAvatar = 1491, //from dbstr_us.txt
|
||||
aaSharedCamouflage = 1494, //from dbstr_us.txt
|
||||
aaConvergenceofSpirits = 1495, //from dbstr_us.txt
|
||||
aaNaturesGuardian = 1498, //from dbstr_us.txt
|
||||
aaEdictofCommand = 1501, //from dbstr_us.txt
|
||||
aaExtendedBurnout = 1504, //from dbstr_us.txt
|
||||
aaGuardianofRo = 1507, //from dbstr_us.txt
|
||||
aaBloodMagic = 1510, //from dbstr_us.txt
|
||||
aaGraverobbing = 1511, //from dbstr_us.txt
|
||||
aaAfflictionMastery = 1514, //from dbstr_us.txt
|
||||
aaGreaterRabidBear = 1517, //from dbstr_us.txt
|
||||
aaAncestralGuard = 1520, //from dbstr_us.txt
|
||||
aaCloakofLight = 1523, //from dbstr_us.txt
|
||||
aaVanquishUndead = 1524, //from dbstr_us.txt
|
||||
aaCloakofShadows = 1527, //from dbstr_us.txt
|
||||
aaWillfulDeath = 1528, //from dbstr_us.txt
|
||||
aaSwiftBlade = 1533, //from dbstr_us.txt
|
||||
aaWickedBlade = 1536, //from dbstr_us.txt
|
||||
aaForcedOpening = 1539, //from dbstr_us.txt
|
||||
aaAppraisal = 1542, //from dbstr_us.txt
|
||||
aaPreciseStrikes = 1543, //from dbstr_us.txt
|
||||
aaHastenedDeath = 1546, //from dbstr_us.txt
|
||||
aaUnflinchingResolve = 1549, //from dbstr_us.txt
|
||||
aaWeightlessSteps = 1552, //from dbstr_us.txt
|
||||
aaHastenedBlades = 1555, //from dbstr_us.txt
|
||||
aaImprovedHarmoniousAttack = 1563, //from dbstr_us.txt
|
||||
aaImprovedBestialFrenzy = 1566, //from dbstr_us.txt
|
||||
aaSongofStone = 1569, //from dbstr_us.txt
|
||||
aaDeepSleep = 1572, //from dbstr_us.txt
|
||||
aaCompanionsGift = 1577, //from dbstr_us.txt
|
||||
aaHastenedDefiance = 1583, //from dbstr_us.txt
|
||||
aaDauntlessPerseverance = 1586, //from dbstr_us.txt
|
||||
aaConcentration = 1587, //from dbstr_us.txt
|
||||
aaEnhancedAggression = 1592, //from dbstr_us.txt
|
||||
aaCallofChallenge = 1597, //from dbstr_us.txt
|
||||
aaCacophony = 1598, //from dbstr_us.txt
|
||||
aaImprovedHeadshot = 1601, //from dbstr_us.txt
|
||||
aaAnatomy = 1604, //from dbstr_us.txt
|
||||
aaFetterofSpirits = 1607, //from dbstr_us.txt
|
||||
aaTrickShot = 1608, //from dbstr_us.txt
|
||||
aaLightningStrikes = 1616, //from dbstr_us.txt
|
||||
aaRelentlessAssault = 1621, //from dbstr_us.txt
|
||||
aaKnightsExpertise = 1624, //from dbstr_us.txt
|
||||
aaSelosEnduringCadence = 1627, //from dbstr_us.txt
|
||||
aaHarmTouch = 7800, //from dbstr_us.txt
|
||||
aaLayonHands = 7850, //from dbstr_us.txt
|
||||
aaLayonHandsRank16 = 7866,
|
||||
|
||||
aaHighestID //this should always be last, and should always
|
||||
//follow the highest AA ID
|
||||
} aaID;
|
||||
*/
|
||||
|
||||
|
||||
typedef enum { //AA IDs
|
||||
aaNone =0,
|
||||
aaInnateStrength =2,//implemented as bonus
|
||||
@@ -2109,21 +1510,6 @@ typedef enum { //AA IDs
|
||||
//follow the highest AA ID
|
||||
} aaID;
|
||||
|
||||
|
||||
//Structure representing the database's AA actions
|
||||
struct AA_DBAction {
|
||||
uint32 reuse_time; //in seconds
|
||||
uint16 spell_id; //spell to cast, SPELL_UNKNOWN=no spell
|
||||
aaTargetType target; //from aaTargetType
|
||||
aaNonspellAction action; //non-spell action to take
|
||||
uint16 mana_cost; //mana the NON-SPELL action costs
|
||||
uint16 duration; //duration of NON-SPELL effect, 0=N/A
|
||||
aaID redux_aa; //AA which reduces reuse time
|
||||
int32 redux_rate; //%/point in redux_aa reduction in reuse time
|
||||
aaID redux_aa2; //AA which reduces reuse time
|
||||
int32 redux_rate2; //%/point in redux_aa reduction in reuse time
|
||||
};
|
||||
|
||||
//Structure representing the database's swarm pet configs
|
||||
struct AA_SwarmPet {
|
||||
uint8 count; //number to summon
|
||||
@@ -2131,23 +1517,6 @@ struct AA_SwarmPet {
|
||||
uint16 duration; //how long they last, in seconds
|
||||
};
|
||||
|
||||
struct AALevelCost_Struct
|
||||
{
|
||||
uint32 Level;
|
||||
uint32 Cost;
|
||||
};
|
||||
|
||||
//assumes that no activatable aa.has more than 5 ranks
|
||||
#define MAX_AA_ACTION_RANKS 20
|
||||
extern AA_DBAction AA_Actions[aaHighestID][MAX_AA_ACTION_RANKS]; //[aaid][rank]
|
||||
extern std::map<uint16, AA_SwarmPet> AA_SwarmPets; //key=spell_id
|
||||
|
||||
#define AA_Choose3(val, v1, v2, v3) (val==1?v1:(val==2?v2:v3))
|
||||
|
||||
extern std::map<uint32,SendAA_Struct*>aas_send;
|
||||
extern std::map<uint32, std::map<uint32, AA_Ability> > aa_effects;
|
||||
extern std::map<uint32, AALevelCost_Struct> AARequiredLevelAndCost;
|
||||
|
||||
enum { //values of AA_Action.action
|
||||
aaActionActivate = 0,
|
||||
aaActionSetEXP = 1,
|
||||
@@ -2167,4 +1536,11 @@ public:
|
||||
uint32 owner_id;
|
||||
};
|
||||
|
||||
enum AATimers
|
||||
{
|
||||
aaTimerRampage,
|
||||
aaTimerWarcry,
|
||||
aaTimerMax
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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
|
||||
*/
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/types.h"
|
||||
#include "masterentity.h"
|
||||
#include "aa_ability.h"
|
||||
|
||||
AA::Rank *AA::Ability::GetMaxRank() {
|
||||
if(!first)
|
||||
return nullptr;
|
||||
|
||||
Rank *current = first;
|
||||
while(current->next) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
AA::Rank *AA::Ability::GetRankByPointsSpent(int current_level) {
|
||||
if(current_level == 0)
|
||||
return nullptr;
|
||||
|
||||
if(!first)
|
||||
return nullptr;
|
||||
|
||||
int i = 1;
|
||||
Rank *current = first;
|
||||
while(current->next) {
|
||||
if(i == current_level) {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
int AA::Ability::GetMaxLevel(Mob *who) {
|
||||
int max_level = 0;
|
||||
Rank *current = first;
|
||||
while(current) {
|
||||
if(!who->CanUseAlternateAdvancementRank(current)) {
|
||||
return max_level;
|
||||
}
|
||||
|
||||
max_level++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return max_level;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 EQEMU_ZONE_AA_ABILITY_H
|
||||
#define EQEMU_ZONE_AA_ABILITY_H
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "aa_rank_effects.h"
|
||||
#include "aa_rank.h"
|
||||
|
||||
class Mob;
|
||||
|
||||
namespace AA
|
||||
{
|
||||
|
||||
class Ability
|
||||
{
|
||||
public:
|
||||
Ability() { }
|
||||
~Ability() { }
|
||||
|
||||
Rank *GetMaxRank();
|
||||
Rank *GetRankByPointsSpent(int current_level);
|
||||
int GetMaxLevel(Mob *who);
|
||||
|
||||
int id;
|
||||
std::string name;
|
||||
int category;
|
||||
int classes;
|
||||
int races;
|
||||
int deities;
|
||||
int drakkin_heritage;
|
||||
int status;
|
||||
bool grant_only;
|
||||
int type;
|
||||
int charges;
|
||||
int first_rank_id;
|
||||
Rank *first;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 EQEMU_ZONE_AA_RANK_H
|
||||
#define EQEMU_ZONE_AA_RANK_H
|
||||
|
||||
namespace AA
|
||||
{
|
||||
|
||||
class Ability;
|
||||
class Rank
|
||||
{
|
||||
public:
|
||||
Rank() { }
|
||||
~Rank() { }
|
||||
|
||||
int id;
|
||||
int upper_hotkey_sid;
|
||||
int lower_hotkey_sid;
|
||||
int title_sid;
|
||||
int desc_sid;
|
||||
int cost;
|
||||
int level_req;
|
||||
int spell;
|
||||
int spell_type;
|
||||
int recast_time;
|
||||
int prev_id;
|
||||
Rank *prev;
|
||||
int next_id;
|
||||
Rank *next;
|
||||
int current_value;
|
||||
int expansion;
|
||||
int total_cost;
|
||||
Ability *base_ability;
|
||||
std::vector<RankEffect> effects;
|
||||
std::map<int, int> prereqs;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 EQEMU_ZONE_AA_RANK_EFFECTS_H
|
||||
#define EQEMU_ZONE_AA_RANK_EFFECTS_H
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include <string>
|
||||
|
||||
namespace AA
|
||||
{
|
||||
|
||||
struct RankEffect
|
||||
{
|
||||
int slot;
|
||||
int effect_id;
|
||||
int base1;
|
||||
int base2;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+191
-144
@@ -44,12 +44,8 @@ void EntityList::CheckClientAggro(Client *around)
|
||||
if (mob->IsClient()) //also ensures that mob != around
|
||||
continue;
|
||||
|
||||
if (mob->CheckWillAggro(around)) {
|
||||
if (mob->IsEngaged())
|
||||
mob->AddToHateList(around);
|
||||
else
|
||||
mob->AddToHateList(around, mob->GetLevel());
|
||||
}
|
||||
if (mob->CheckWillAggro(around) && !mob->CheckAggro(around))
|
||||
mob->AddToHateList(around, 25);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,10 +156,21 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GREEN ) {
|
||||
towho->Message(0, "...%s is red to me (basically)", mob->GetName(),
|
||||
dist2, iAggroRange2);
|
||||
return;
|
||||
if (RuleB(Aggro, UseLevelAggro))
|
||||
{
|
||||
if (GetLevel() < 18 && mob->GetLevelCon(GetLevel()) == CON_GREEN && GetBodyType() != 3)
|
||||
{
|
||||
towho->Message(0, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GREEN ) {
|
||||
towho->Message(0, "...%s is red to me (basically)", mob->GetName(),
|
||||
dist2, iAggroRange2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(verbose) {
|
||||
@@ -289,6 +296,14 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
// Don't aggro new clients if we are already engaged unless PROX_AGGRO is set
|
||||
if (IsEngaged() && (!GetSpecialAbility(PROX_AGGRO) || (GetSpecialAbility(PROX_AGGRO) && !CombatRange(mob)))) {
|
||||
Log.Out(Logs::Moderate, Logs::Aggro,
|
||||
"%s is in combat, and does not have prox_aggro, or does and is out of combat range with %s",
|
||||
GetName(), mob->GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
//im not sure I understand this..
|
||||
//if I have an owner and it is not this mob, then I cannot
|
||||
//aggro this mob...???
|
||||
@@ -317,11 +332,12 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
int heroicCHA_mod = mob->itembonuses.HeroicCHA/25; // 800 Heroic CHA cap
|
||||
if(heroicCHA_mod > THREATENLY_ARRGO_CHANCE)
|
||||
heroicCHA_mod = THREATENLY_ARRGO_CHANCE;
|
||||
if
|
||||
if (RuleB(Aggro, UseLevelAggro) &&
|
||||
(
|
||||
//old InZone check taken care of above by !mob->CastToClient()->Connected()
|
||||
(
|
||||
( GetINT() <= RuleI(Aggro, IntAggroThreshold) )
|
||||
( GetLevel() >= 18 )
|
||||
||(GetBodyType() == 3)
|
||||
||( mob->IsClient() && mob->CastToClient()->IsSitting() )
|
||||
||( mob->GetLevelCon(GetLevel()) != CON_GREEN )
|
||||
|
||||
@@ -340,13 +356,47 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
//FatherNiwtit: make sure we can see them. last since it is very expensive
|
||||
if(CheckLosFN(mob)) {
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
return( mod_will_aggro(mob, this) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if
|
||||
(
|
||||
//old InZone check taken care of above by !mob->CastToClient()->Connected()
|
||||
(
|
||||
( GetINT() <= RuleI(Aggro, IntAggroThreshold) )
|
||||
||( mob->IsClient() && mob->CastToClient()->IsSitting() )
|
||||
||( mob->GetLevelCon(GetLevel()) != CON_GREEN )
|
||||
|
||||
)
|
||||
&&
|
||||
(
|
||||
(
|
||||
fv == FACTION_SCOWLS
|
||||
||
|
||||
(mob->GetPrimaryFaction() != GetPrimaryFaction() && mob->GetPrimaryFaction() == -4 && GetOwner() == nullptr)
|
||||
||
|
||||
(
|
||||
fv == FACTION_THREATENLY
|
||||
&& zone->random.Roll(THREATENLY_ARRGO_CHANCE - heroicCHA_mod)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
//FatherNiwtit: make sure we can see them. last since it is very expensive
|
||||
if(CheckLosFN(mob)) {
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Check aggro for %s target %s.", GetName(), mob->GetName());
|
||||
return( mod_will_aggro(mob, this) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Is In zone?:%d\n", mob->InZone());
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Dist^2: %f\n", dist2);
|
||||
@@ -427,11 +477,20 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
if (sender->GetPrimaryFaction() == 0 )
|
||||
return; // well, if we dont have a faction set, we're gonna be indiff to everybody
|
||||
|
||||
if (sender->HasAssistAggro())
|
||||
return;
|
||||
|
||||
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
||||
NPC *mob = it->second;
|
||||
if (!mob)
|
||||
continue;
|
||||
|
||||
if (mob->CheckAggro(attacker))
|
||||
continue;
|
||||
|
||||
if (sender->NPCAssistCap() >= RuleI(Combat, NPCAssistCap))
|
||||
break;
|
||||
|
||||
float r = mob->GetAssistRange();
|
||||
r = r * r;
|
||||
|
||||
@@ -449,7 +508,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
{
|
||||
//if they are in range, make sure we are not green...
|
||||
//then jump in if they are our friend
|
||||
if(attacker->GetLevelCon(mob->GetLevel()) != CON_GREEN)
|
||||
if(mob->GetLevel() >= 50 || attacker->GetLevelCon(mob->GetLevel()) != CON_GREEN)
|
||||
{
|
||||
bool useprimfaction = false;
|
||||
if(mob->GetPrimaryFaction() == sender->CastToNPC()->GetPrimaryFaction())
|
||||
@@ -468,11 +527,12 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
if(mob->CheckLosFN(sender)) {
|
||||
#if (EQDEBUG>=5)
|
||||
Log.Out(Logs::General, Logs::None, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
|
||||
sender->GetName(), attacker->GetName(), mob->GetName(),
|
||||
attacker->GetName(), DistanceSquared(mob->GetPosition(),
|
||||
sender->GetName(), attacker->GetName(), mob->GetName(),
|
||||
attacker->GetName(), DistanceSquared(mob->GetPosition(),
|
||||
sender->GetPosition()), fabs(sender->GetZ()+mob->GetZ()));
|
||||
#endif
|
||||
mob->AddToHateList(attacker, 1, 0, false);
|
||||
mob->AddToHateList(attacker, 25, 0, false);
|
||||
sender->AddAssistCap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -880,11 +940,11 @@ bool Mob::CombatRange(Mob* other)
|
||||
float _DistNoRoot = DistanceSquared(m_Position, other->GetPosition());
|
||||
|
||||
if (GetSpecialAbility(NPC_CHASE_DISTANCE)){
|
||||
|
||||
|
||||
bool DoLoSCheck = true;
|
||||
float max_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 0));
|
||||
float min_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 1));
|
||||
|
||||
|
||||
if (GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 2))
|
||||
DoLoSCheck = false; //Ignore line of sight check
|
||||
|
||||
@@ -897,10 +957,10 @@ bool Mob::CombatRange(Mob* other)
|
||||
min_dist = size_mod; //Default to melee range
|
||||
else
|
||||
min_dist = min_dist * min_dist;
|
||||
|
||||
|
||||
if ((DoLoSCheck && CheckLastLosState()) && (_DistNoRoot >= min_dist && _DistNoRoot <= max_dist))
|
||||
SetPseudoRoot(true);
|
||||
else
|
||||
SetPseudoRoot(true);
|
||||
else
|
||||
SetPseudoRoot(false);
|
||||
}
|
||||
|
||||
@@ -919,7 +979,7 @@ bool Mob::CheckLosFN(Mob* other) {
|
||||
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
||||
|
||||
SetLastLosState(Result);
|
||||
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -954,11 +1014,25 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
|
||||
}
|
||||
|
||||
//offensive spell aggro
|
||||
int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
||||
{
|
||||
if (NoDetrimentalSpellAggro(spell_id))
|
||||
return 0;
|
||||
|
||||
int32 AggroAmount = 0;
|
||||
int32 nonModifiedAggro = 0;
|
||||
uint16 slevel = GetLevel();
|
||||
bool dispel = false;
|
||||
bool on_hatelist = target ? target->CheckAggro(this) : false;
|
||||
int proc_cap = RuleI(Aggro, MaxScalingProcAggro);
|
||||
int hate_cap = isproc && proc_cap != -1 ? proc_cap : 1200;
|
||||
|
||||
int32 target_hp = target ? target->GetMaxHP() : 18000; // default to max
|
||||
int32 default_aggro = 25;
|
||||
if (target_hp >= 18000) // max
|
||||
default_aggro = hate_cap;
|
||||
else if (target_hp >= 390) // min, 390 is the first number with int division that is 26
|
||||
default_aggro = target_hp / 15;
|
||||
|
||||
for (int o = 0; o < EFFECT_COUNT; o++) {
|
||||
switch (spells[spell_id].effectid[o]) {
|
||||
@@ -972,7 +1046,7 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
case SE_MovementSpeed: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount += (2 + ((slevel * slevel) / 8));
|
||||
AggroAmount += default_aggro;
|
||||
break;
|
||||
}
|
||||
case SE_AttackSpeed:
|
||||
@@ -980,60 +1054,32 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
case SE_AttackSpeed3: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 100)
|
||||
AggroAmount += (5 + ((slevel * slevel) / 5));
|
||||
AggroAmount += default_aggro;
|
||||
break;
|
||||
}
|
||||
case SE_Stun: {
|
||||
int val = (5 + ((slevel * slevel) / 6));
|
||||
if (isproc && RuleI(Aggro,MaxStunProcAggro) > -1 && (val > RuleI(Aggro,MaxStunProcAggro)))
|
||||
val = RuleI(Aggro,MaxStunProcAggro);
|
||||
AggroAmount += val;
|
||||
case SE_Stun:
|
||||
case SE_Blind:
|
||||
case SE_Mez:
|
||||
case SE_Charm:
|
||||
case SE_Fear:
|
||||
AggroAmount += default_aggro;
|
||||
break;
|
||||
}
|
||||
case SE_Blind: {
|
||||
AggroAmount += (5 + ((slevel * slevel) / 6));
|
||||
case SE_Root:
|
||||
AggroAmount += 10;
|
||||
break;
|
||||
}
|
||||
case SE_Mez: {
|
||||
AggroAmount += (5 + ((slevel * slevel) / 5));
|
||||
break;
|
||||
}
|
||||
case SE_Charm: {
|
||||
AggroAmount += (5 + ((slevel * slevel) / 5));
|
||||
break;
|
||||
}
|
||||
case SE_Root: {
|
||||
AggroAmount += (2 + ((slevel * slevel) / 8));
|
||||
break;
|
||||
}
|
||||
case SE_Fear: {
|
||||
AggroAmount += (5 + ((slevel * slevel) / 6));
|
||||
break;
|
||||
}
|
||||
case SE_ATK:
|
||||
case SE_ACv2:
|
||||
case SE_ArmorClass: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount -= val * 2;
|
||||
AggroAmount += default_aggro;
|
||||
break;
|
||||
}
|
||||
case SE_ATK:
|
||||
case SE_ResistMagic:
|
||||
case SE_ResistFire:
|
||||
case SE_ResistCold:
|
||||
case SE_ResistPoison:
|
||||
case SE_ResistDisease: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount -= val * 3;
|
||||
break;
|
||||
}
|
||||
case SE_ResistAll: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount -= val * 6;
|
||||
break;
|
||||
}
|
||||
case SE_ResistDisease:
|
||||
case SE_STR:
|
||||
case SE_STA:
|
||||
case SE_DEX:
|
||||
@@ -1043,32 +1089,31 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
case SE_CHA: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount -= val * 2;
|
||||
AggroAmount += 10;
|
||||
break;
|
||||
}
|
||||
case SE_ResistAll: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount += 50;
|
||||
break;
|
||||
}
|
||||
case SE_AllStats: {
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
if (val < 0)
|
||||
AggroAmount -= val * 6;
|
||||
AggroAmount += 70;
|
||||
break;
|
||||
}
|
||||
case SE_BardAEDot: {
|
||||
AggroAmount += slevel * 2;
|
||||
case SE_BardAEDot:
|
||||
AggroAmount += 10;
|
||||
break;
|
||||
}
|
||||
case SE_SpinTarget: {
|
||||
AggroAmount += (5 + ((slevel * slevel) / 5));
|
||||
break;
|
||||
}
|
||||
case SE_SpinTarget:
|
||||
case SE_Amnesia:
|
||||
case SE_Silence: {
|
||||
AggroAmount += slevel * 2;
|
||||
case SE_Silence:
|
||||
case SE_Destroy:
|
||||
AggroAmount += default_aggro;
|
||||
break;
|
||||
}
|
||||
case SE_Destroy: {
|
||||
AggroAmount += slevel * 2;
|
||||
break;
|
||||
}
|
||||
// unsure -- leave them this for now
|
||||
case SE_Harmony:
|
||||
case SE_CastingLevel:
|
||||
case SE_MeleeMitigation:
|
||||
@@ -1091,6 +1136,7 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
AggroAmount += slevel * 2;
|
||||
break;
|
||||
}
|
||||
// unsure -- leave them this for now
|
||||
case SE_CurrentMana:
|
||||
case SE_ManaRegen_v2:
|
||||
case SE_ManaPool:
|
||||
@@ -1101,123 +1147,124 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
break;
|
||||
}
|
||||
case SE_CancelMagic:
|
||||
case SE_DispelDetrimental: {
|
||||
AggroAmount += slevel;
|
||||
case SE_DispelDetrimental:
|
||||
dispel = true;
|
||||
break;
|
||||
}
|
||||
case SE_ReduceHate:
|
||||
case SE_InstantHate: {
|
||||
case SE_InstantHate:
|
||||
nonModifiedAggro = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsAEDurationSpell(spell_id))
|
||||
AggroAmount /= 2;
|
||||
if (IsBardSong(spell_id) && AggroAmount > 40)
|
||||
AggroAmount = 40; // bard songs seem to cap to 40 for most of their spells?
|
||||
|
||||
if (spells[spell_id].HateAdded > 0)
|
||||
if (dispel && target && target->GetHateAmount(this) < 100)
|
||||
AggroAmount += 50;
|
||||
|
||||
if (spells[spell_id].HateAdded > 0) // overrides the hate (ex. tash)
|
||||
AggroAmount = spells[spell_id].HateAdded;
|
||||
|
||||
if (IsBardSong(spell_id))
|
||||
AggroAmount = AggroAmount * RuleI(Aggro, SongAggroMod) / 100;
|
||||
if (GetOwner() && IsPet())
|
||||
AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100;
|
||||
|
||||
if (AggroAmount > 0) {
|
||||
|
||||
// hate focus ignored on first action for some reason
|
||||
if (!on_hatelist && AggroAmount > 0) {
|
||||
int HateMod = RuleI(Aggro, SpellAggroMod);
|
||||
|
||||
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
|
||||
AggroAmount = (AggroAmount * HateMod) / 100;
|
||||
|
||||
//made up number probably scales a bit differently on live but it seems like it will be close enough
|
||||
//every time you cast on live you get a certain amount of "this is a spell" aggro
|
||||
//confirmed by EQ devs to be 100 exactly at level 85. From their wording it doesn't seem like it's affected
|
||||
//by hate modifiers either.
|
||||
//AggroAmount += (slevel*slevel/72);
|
||||
// Saved so I can reimplement it;
|
||||
// this should only be on the spell to aggro the npc not every spell
|
||||
|
||||
}
|
||||
|
||||
// initial aggro gets a bonus 100 besides for dispel or hate override
|
||||
// We add this 100 in AddToHateList so we need to account for the oddities here
|
||||
if (dispel && spells[spell_id].HateAdded > 0 && !on_hatelist)
|
||||
AggroAmount -= 100;
|
||||
|
||||
return AggroAmount + spells[spell_id].bonushate + nonModifiedAggro;
|
||||
}
|
||||
|
||||
//healing and buffing aggro
|
||||
int32 Mob::CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible)
|
||||
int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possible)
|
||||
{
|
||||
int32 AggroAmount = 0;
|
||||
auto target_level = target ? target->GetLevel() : 1;
|
||||
bool ignore_default_buff = false; // rune/hot don't use the default 9, HP buffs that heal (virtue) do use the default
|
||||
|
||||
for (int o = 0; o < EFFECT_COUNT; o++) {
|
||||
switch (spells[spell_id].effectid[o]) {
|
||||
case SE_CurrentHP: {
|
||||
AggroAmount += IsBuffSpell(spell_id) ? spells[spell_id].mana / 4 : spells[spell_id].mana;
|
||||
case SE_CurrentHP: {
|
||||
if (heal_possible == 0) {
|
||||
AggroAmount += 1;
|
||||
break;
|
||||
}
|
||||
case SE_Rune: {
|
||||
AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[0], spells[spell_id].base[0], spells[spell_id].max[o], GetLevel(), spell_id) * 2;
|
||||
break;
|
||||
}
|
||||
case SE_HealOverTime: {
|
||||
AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], GetLevel(), spell_id);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
// hate based on base healing power of the spell
|
||||
int val = CalcSpellEffectValue_formula(spells[spell_id].formula[o],
|
||||
spells[spell_id].base[o], spells[spell_id].max[o], GetLevel(), spell_id);
|
||||
if (val > 0) {
|
||||
if (heal_possible < val)
|
||||
val = heal_possible; // capped to amount healed
|
||||
val = 2 * val / 3; // 3:2 ratio
|
||||
|
||||
if (target_level > 50 && val > 1500)
|
||||
val = 1500; // target 51+ seems ~1500
|
||||
else if (target_level <= 50 && val > 800)
|
||||
val = 800; // per live patch notes, capped to 800
|
||||
}
|
||||
AggroAmount += std::max(val, 1);
|
||||
break;
|
||||
}
|
||||
case SE_Rune:
|
||||
AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[o],
|
||||
spells[spell_id].base[o], spells[spell_id].max[o], GetLevel(), spell_id) * 2;
|
||||
ignore_default_buff = true;
|
||||
break;
|
||||
case SE_HealOverTime:
|
||||
AggroAmount += 10;
|
||||
ignore_default_buff = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsBardSong(spell_id))
|
||||
AggroAmount = AggroAmount * RuleI(Aggro, SongAggroMod) / 100;
|
||||
if (GetOwner() && IsPet())
|
||||
AggroAmount = AggroAmount * RuleI(Aggro, PetSpellAggroMod) / 100;
|
||||
|
||||
if (!ignore_default_buff && IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id))
|
||||
AggroAmount = IsBardSong(spell_id) ? 2 : 9;
|
||||
|
||||
if (AggroAmount > 0) {
|
||||
int HateMod = RuleI(Aggro, SpellAggroMod);
|
||||
|
||||
HateMod += GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
|
||||
//Live AA - Spell casting subtlety
|
||||
HateMod += aabonuses.hatemod + spellbonuses.hatemod + itembonuses.hatemod;
|
||||
|
||||
AggroAmount = (AggroAmount * HateMod) / 100;
|
||||
|
||||
//made up number probably scales a bit differently on live but it seems like it will be close enough
|
||||
//every time you cast on live you get a certain amount of "this is a spell" aggro
|
||||
//confirmed by EQ devs to be 100 exactly at level 85. From their wording it doesn't seem like it's affected
|
||||
//by hate modifiers either.
|
||||
//AggroAmount += (slevel*slevel/72); // Moved Below
|
||||
}
|
||||
|
||||
if (AggroAmount < 0)
|
||||
return 0;
|
||||
else
|
||||
return AggroAmount;
|
||||
return std::max(0, AggroAmount);
|
||||
}
|
||||
|
||||
void Mob::AddFeignMemory(Client* attacker) {
|
||||
if(feign_memory_list.empty() && AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Start(AIfeignremember_delay);
|
||||
if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Start(AIfeignremember_delay);
|
||||
feign_memory_list.insert(attacker->CharacterID());
|
||||
}
|
||||
|
||||
void Mob::RemoveFromFeignMemory(Client* attacker) {
|
||||
feign_memory_list.erase(attacker->CharacterID());
|
||||
if(feign_memory_list.empty() && AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Disable();
|
||||
if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Disable();
|
||||
if(feign_memory_list.empty())
|
||||
{
|
||||
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
if(AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Disable();
|
||||
if(AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::ClearFeignMemory() {
|
||||
std::set<uint32>::iterator RememberedCharID = feign_memory_list.begin();
|
||||
auto RememberedCharID = feign_memory_list.begin();
|
||||
while (RememberedCharID != feign_memory_list.end())
|
||||
{
|
||||
Client* remember_client = entity_list.GetClientByCharID(*RememberedCharID);
|
||||
@@ -1229,8 +1276,8 @@ void Mob::ClearFeignMemory() {
|
||||
feign_memory_list.clear();
|
||||
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
if(AIfeignremember_timer != nullptr)
|
||||
AIfeignremember_timer->Disable();
|
||||
if(AI_feign_remember_timer != nullptr)
|
||||
AI_feign_remember_timer->Disable();
|
||||
}
|
||||
|
||||
bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
|
||||
@@ -1249,10 +1296,10 @@ bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
|
||||
return true;
|
||||
|
||||
float resist_check = 0;
|
||||
|
||||
|
||||
if(IsCharmSpell(spell_id)) {
|
||||
|
||||
if (spells[spell_id].powerful_flag == -1) //If charm spell has this set(-1), it can not break till end of duration.
|
||||
if (spells[spell_id].no_resist) //If charm spell has this set(-1), it can not break till end of duration.
|
||||
return true;
|
||||
|
||||
//1: The mob has a default 25% chance of being allowed a resistance check against the charm.
|
||||
@@ -1265,7 +1312,7 @@ bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
|
||||
resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0, false, true);
|
||||
|
||||
//2: The mob makes a resistance check against the charm
|
||||
if (resist_check == 100)
|
||||
if (resist_check == 100)
|
||||
return true;
|
||||
|
||||
else
|
||||
|
||||
+1220
-1480
File diff suppressed because it is too large
Load Diff
+5
-3
@@ -26,8 +26,10 @@ target to center around.
|
||||
class Zone;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#if (!defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1900))
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
@@ -54,7 +56,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||
:Mob
|
||||
(
|
||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
),
|
||||
remove_timer(lifetime),
|
||||
spell_timer(0)
|
||||
|
||||
+4
-4
@@ -34,10 +34,10 @@ public:
|
||||
~Beacon();
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr) { return false; }
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
|
||||
+1367
-1221
File diff suppressed because it is too large
Load Diff
+3163
-11332
File diff suppressed because it is too large
Load Diff
+200
-159
@@ -1,3 +1,21 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 BOT_H
|
||||
#define BOT_H
|
||||
|
||||
@@ -7,9 +25,11 @@
|
||||
#include "mob.h"
|
||||
#include "client.h"
|
||||
#include "pets.h"
|
||||
#include "heal_rotation.h"
|
||||
#include "groups.h"
|
||||
#include "corpse.h"
|
||||
#include "zonedb.h"
|
||||
#include "bot_database.h"
|
||||
#include "string_ids.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/global_define.h"
|
||||
@@ -18,6 +38,8 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#define BOT_DEFAULT_FOLLOW_DISTANCE 184
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
const int BotAISpellRange = 100; // TODO: Write a method that calcs what the bot's spell range is based on spell, equipment, AA, whatever and replace this
|
||||
@@ -27,8 +49,6 @@ const int DisciplineReuseStart = MaxSpellTimer + 1;
|
||||
const int MaxTimer = MaxSpellTimer + MaxDisciplineTimer;
|
||||
const int MaxStances = 7;
|
||||
const int MaxSpellTypes = 16;
|
||||
const int MaxHealRotationMembers = 6;
|
||||
const int MaxHealRotationTargets = 3;
|
||||
|
||||
enum BotStanceType {
|
||||
BotStancePassive,
|
||||
@@ -37,9 +57,58 @@ enum BotStanceType {
|
||||
BotStanceReactive,
|
||||
BotStanceAggressive,
|
||||
BotStanceBurn,
|
||||
BotStanceBurnAE
|
||||
BotStanceBurnAE,
|
||||
BotStanceUnknown
|
||||
};
|
||||
|
||||
#define BOT_STANCE_COUNT 8
|
||||
#define VALIDBOTSTANCE(x) ((x >= (int)BotStancePassive && x <= (int)BotStanceBurnAE) ? ((BotStanceType)x) : (BotStanceUnknown))
|
||||
|
||||
static const std::string bot_stance_name[BOT_STANCE_COUNT] = {
|
||||
"Passive", // 0
|
||||
"Balanced", // 1
|
||||
"Efficient", // 2
|
||||
"Reactive", // 3
|
||||
"Aggressive", // 4
|
||||
"Burn", // 5
|
||||
"BurnAE", // 6
|
||||
"Unknown" // 7
|
||||
};
|
||||
|
||||
static const char* GetBotStanceName(int stance_id) { return bot_stance_name[VALIDBOTSTANCE(stance_id)].c_str(); }
|
||||
|
||||
#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::legacy::EQUIPMENT_BEGIN && x <= EQEmu::legacy::EQUIPMENT_END) ? (x) : ((x == EQEmu::legacy::SlotPowerSource) ? (22) : (23)))
|
||||
|
||||
static std::string bot_equip_slot_name[EQEmu::legacy::EQUIPMENT_SIZE + 2] =
|
||||
{
|
||||
"Charm", // MainCharm
|
||||
"Left Ear", // MainEar1
|
||||
"Head", // MainHead
|
||||
"Face", // MainFace
|
||||
"Right Ear", // MainEar2
|
||||
"Neck", // MainNeck
|
||||
"Shoulders", // MainShoulders
|
||||
"Arms", // MainArms
|
||||
"Back", // MainBack
|
||||
"Left Wrist", // MainWrist1
|
||||
"Right Wrist", // MainWrist2
|
||||
"Range", // MainRange
|
||||
"Hands", // MainHands
|
||||
"Primary Hand", // MainPrimary
|
||||
"Secondary Hand", // MainSecondary
|
||||
"Left Finger", // MainFinger1
|
||||
"Right Finger", // MainFinger2
|
||||
"Chest", // MainChest
|
||||
"Legs", // MainLegs
|
||||
"Feet", // MainFeet
|
||||
"Waist", // MainWaist
|
||||
"Ammo", // MainAmmo
|
||||
"Power Source", // 22 (MainPowerSource = 9999)
|
||||
"Unknown"
|
||||
};
|
||||
|
||||
static const char* GetBotEquipSlotName(int slot_id) { return bot_equip_slot_name[VALIDBOTEQUIPSLOT(slot_id)].c_str(); }
|
||||
|
||||
enum SpellTypeIndex {
|
||||
SpellType_NukeIndex,
|
||||
SpellType_HealIndex,
|
||||
@@ -60,6 +129,7 @@ enum SpellTypeIndex {
|
||||
};
|
||||
|
||||
class Bot : public NPC {
|
||||
friend class Mob;
|
||||
public:
|
||||
// Class enums
|
||||
enum BotfocusType { //focus types
|
||||
@@ -107,7 +177,7 @@ public:
|
||||
BotRoleRaidHealer
|
||||
};
|
||||
|
||||
enum EqExpansions {
|
||||
enum EqExpansions { // expansions are off..EQ should be '0'
|
||||
ExpansionNone,
|
||||
ExpansionEQ,
|
||||
ExpansionRoK,
|
||||
@@ -135,10 +205,10 @@ public:
|
||||
Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData);
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||
virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); }
|
||||
@@ -153,10 +223,10 @@ public:
|
||||
|
||||
// Class Methods
|
||||
bool IsValidRaceClassCombo();
|
||||
static bool IsValidRaceClassCombo(uint16 r, uint8 c);
|
||||
bool IsValidName();
|
||||
bool IsBotNameAvailable(std::string* errorMessage);
|
||||
bool DeleteBot(std::string* errorMessage);
|
||||
void Spawn(Client* botCharacterOwner, std::string* errorMessage);
|
||||
static bool IsValidName(std::string& name);
|
||||
void Spawn(Client* botCharacterOwner);
|
||||
virtual void SetLevel(uint8 in_level, bool command = false);
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
virtual bool Process();
|
||||
@@ -168,29 +238,30 @@ public:
|
||||
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
|
||||
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
||||
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
||||
virtual bool AvoidDamage(Mob* other, int32 &damage, bool CanRiposte);
|
||||
virtual int GetMonkHandToHandDamage(void);
|
||||
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);
|
||||
virtual int GetHandToHandDamage(void);
|
||||
virtual bool TryFinishingBlow(Mob *defender, EQEmu::skills::SkillType skillinuse);
|
||||
virtual void DoRiposte(Mob* defender);
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(SkillOffense)) * 9 / 10); }
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQEmu::skills::SkillOffense)) * 9 / 10); }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
uint32 GetTotalATK();
|
||||
uint32 GetATKRating();
|
||||
uint16 GetPrimarySkillValue();
|
||||
uint16 MaxSkill(SkillUseTypes skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(SkillUseTypes skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
virtual void DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance=false);
|
||||
uint16 MaxSkill(EQEmu::skills::SkillType skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(EQEmu::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
virtual void DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance = false);
|
||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||
virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10);
|
||||
virtual void RogueAssassinate(Mob* other);
|
||||
virtual void DoClassAttacks(Mob *target, bool IsRiposte=false);
|
||||
virtual bool TryHeadShot(Mob* defender, SkillUseTypes skillInUse);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime =0);
|
||||
virtual void ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg);
|
||||
virtual bool TryHeadShot(Mob* defender, EQEmu::skills::SkillType skillInUse);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
|
||||
virtual void ApplySpecialAttackMod(EQEmu::skills::SkillType skill, int32 &dmg, int32 &mindmg);
|
||||
bool CanDoSpecialAttack(Mob *other);
|
||||
virtual int32 CheckAggroAmount(uint16 spellid);
|
||||
virtual void CalcBonuses();
|
||||
void CalcItemBonuses();
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0);
|
||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
|
||||
inline virtual bool IsPet() { return false; }
|
||||
@@ -198,14 +269,14 @@ public:
|
||||
virtual Mob* GetOwner();
|
||||
virtual Mob* GetOwnerOrSelf();
|
||||
inline virtual bool HasOwner() { return (GetBotOwner() ? true : false); }
|
||||
virtual int32 CheckHealAggroAmount(uint16 spellid, uint32 heal_possible = 0);
|
||||
virtual int32 CheckHealAggroAmount(uint16 spellid, Mob *target, uint32 heal_possible = 0);
|
||||
virtual int32 CalcMaxMana();
|
||||
virtual void SetAttackTimer();
|
||||
uint32 GetClassHPFactor();
|
||||
virtual int32 CalcMaxHP();
|
||||
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, uint16 slot, bool &stopLogic);
|
||||
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, uint16 slot, bool &stopLogic);
|
||||
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, uint16 slot, bool &stopLogic);
|
||||
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
|
||||
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
|
||||
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
|
||||
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
|
||||
void Camp(bool databaseSave = true);
|
||||
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false);
|
||||
@@ -226,18 +297,7 @@ public:
|
||||
bool HasOrMayGetAggro();
|
||||
void SetDefaultBotStance();
|
||||
void CalcChanceToCast();
|
||||
void CreateHealRotation( Mob* target, uint32 timer = 10000 );
|
||||
bool AddHealRotationMember( Bot* healer );
|
||||
bool RemoveHealRotationMember( Bot* healer );
|
||||
bool AddHealRotationTarget( Mob* target );
|
||||
//bool AddHealRotationTarget( const char *targetName, int index);
|
||||
bool AddHealRotationTarget( Mob* target, int index);
|
||||
bool RemoveHealRotationTarget( Mob* target );
|
||||
bool RemoveHealRotationTarget( int index);
|
||||
void NotifyNextHealRotationMember( bool notifyNow = false );
|
||||
void ClearHealRotationLeader() { _healRotationLeader = 0; }
|
||||
void ClearHealRotationMembers();
|
||||
void ClearHealRotationTargets();
|
||||
|
||||
inline virtual int32 GetMaxStat();
|
||||
inline virtual int32 GetMaxResist();
|
||||
inline virtual int32 GetMaxSTR();
|
||||
@@ -295,6 +355,9 @@ public:
|
||||
virtual bool AI_PursueCastCheck();
|
||||
virtual bool AI_IdleCastCheck();
|
||||
bool AIHealRotation(Mob* tar, bool useFastHeals);
|
||||
bool GetPauseAI() { return _pauseAI; }
|
||||
void SetPauseAI(bool pause_flag) { _pauseAI = pause_flag; }
|
||||
|
||||
|
||||
// Mob AI Virtual Override Methods
|
||||
virtual void AI_Process();
|
||||
@@ -310,65 +373,35 @@ public:
|
||||
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
||||
virtual float GetAOERange(uint16 spell_id);
|
||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
||||
virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0);
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr);
|
||||
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0,
|
||||
uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr, uint32 aa_id = 0);
|
||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar);
|
||||
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
||||
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF);
|
||||
|
||||
// Bot Action Command Methods
|
||||
bool MesmerizeTarget(Mob* target);
|
||||
bool Bot_Command_Resist(int resisttype, int level);
|
||||
bool Bot_Command_DireTarget(int diretype, Mob *target);
|
||||
bool Bot_Command_CharmTarget(int charmtype, Mob *target);
|
||||
bool Bot_Command_CalmTarget(Mob *target);
|
||||
bool Bot_Command_RezzTarget(Mob *target);
|
||||
bool Bot_Command_Cure(int curetype, int level);
|
||||
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQEmu::CastingSlot slot);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
|
||||
|
||||
// Bot Equipment & Inventory Class Methods
|
||||
void BotTradeSwapItem(Client* client, int16 lootSlot, const ItemInst* inst, const ItemInst* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap = true);
|
||||
void BotTradeAddItem(uint32 id, const ItemInst* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb = true);
|
||||
void EquipBot(std::string* errorMessage);
|
||||
bool CheckLoreConflict(const Item_Struct* item);
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = m_inv.FindBrightestLightType(); m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); }
|
||||
bool CheckLoreConflict(const EQEmu::ItemBase* item);
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type[EQEmu::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]); }
|
||||
|
||||
// Static Class Methods
|
||||
static void SaveBotGroup(Group* botGroup, std::string botGroupName, std::string* errorMessage);
|
||||
static void DeleteBotGroup(std::string botGroupName, std::string* errorMessage);
|
||||
static std::list<BotGroup> LoadBotGroup(std::string botGroupName, std::string* errorMessage);
|
||||
static uint32 CanLoadBotGroup(uint32 botOwnerCharacterId, std::string botGroupName, std::string* errorMessage);
|
||||
static uint32 GetBotGroupIdByBotGroupName(std::string botGroupName, std::string* errorMessage);
|
||||
static uint32 GetBotGroupLeaderIdByBotGroupName(std::string botGroupName);
|
||||
static std::list<BotGroupList> GetBotGroupListByBotOwnerCharacterId(uint32 botOwnerCharacterId, std::string* errorMessage);
|
||||
static bool DoesBotGroupNameExist(std::string botGroupName);
|
||||
// Static Class Methods
|
||||
//static void DestroyBotRaidObjects(Client* client); // Can be removed after bot raids are dumped
|
||||
static uint32 GetBotIDByBotName(std::string botName);
|
||||
static Bot* LoadBot(uint32 botID, std::string* errorMessage);
|
||||
static std::list<BotsAvailableList> GetBotList(uint32 botOwnerCharacterID, std::string* errorMessage);
|
||||
static void ProcessBotCommands(Client *c, const Seperator *sep);
|
||||
static std::list<SpawnedBotsList> ListSpawnedBots(uint32 characterID, std::string* errorMessage);
|
||||
static uint32 SpawnedBotCount(uint32 botOwnerCharacterID, std::string* errorMessage);
|
||||
static uint32 CreatedBotCount(uint32 botOwnerCharacterID, std::string* errorMessage);
|
||||
static uint32 AllowedBotSpawns(uint32 botOwnerCharacterID, std::string* errorMessage);
|
||||
static uint32 GetBotOwnerCharacterID(uint32 botID, std::string* errorMessage);
|
||||
static Bot* LoadBot(uint32 botID);
|
||||
static uint32 SpawnedBotCount(uint32 botOwnerCharacterID);
|
||||
static void LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp);
|
||||
//static bool SetBotOwnerCharacterID(uint32 botID, uint32 botOwnerCharacterID, std::string* errorMessage);
|
||||
static std::string ClassIdToString(uint16 classId);
|
||||
static std::string RaceIdToString(uint16 raceId);
|
||||
static bool IsBotAttackAllowed(Mob* attacker, Mob* target, bool& hasRuleDefined);
|
||||
static void BotGroupOrderFollow(Group* group, Client* client);
|
||||
static void BotGroupOrderGuard(Group* group, Client* client);
|
||||
static void BotGroupOrderAttack(Group* group, Mob* target, Client* client);
|
||||
static void BotGroupSummon(Group* group, Client* client);
|
||||
static Bot* GetBotByBotClientOwnerAndBotName(Client* c, std::string botName);
|
||||
static void ProcessBotGroupInvite(Client* c, std::string botName);
|
||||
static void ProcessBotGroupDisband(Client* c, std::string botName);
|
||||
static void BotOrderCampAll(Client* c);
|
||||
static void BotHealRotationsClear( Client* c );
|
||||
static void ProcessBotInspectionRequest(Bot* inspectedBot, Client* client);
|
||||
static std::list<uint32> GetGroupedBotsByGroupId(uint32 groupId, std::string* errorMessage);
|
||||
static void LoadAndSpawnAllZonedBots(Client* botOwner);
|
||||
static bool GroupHasBot(Group* group);
|
||||
static Bot* GetFirstBotInGroup(Group* group);
|
||||
@@ -406,13 +439,10 @@ public:
|
||||
static BotSpell GetBestBotSpellForCure(Bot* botCaster, Mob* target);
|
||||
static BotSpell GetBestBotSpellForResistDebuff(Bot* botCaster, Mob* target);
|
||||
static NPCType CreateDefaultNPCTypeStructForBot(std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender);
|
||||
static std::list<Bot*> GetBotsInHealRotation( Bot* leader );
|
||||
|
||||
// Static Bot Group Methods
|
||||
static bool AddBotToGroup(Bot* bot, Group* group);
|
||||
static bool RemoveBotFromGroup(Bot* bot, Group* group);
|
||||
static bool BotGroupCreate(std::string botGroupLeaderName);
|
||||
static bool BotGroupCreate(Bot* botGroupLeader);
|
||||
static bool GroupHasClass(Group* group, uint8 classId);
|
||||
static bool GroupHasClericClass(Group* group) { return GroupHasClass(group, CLERIC); }
|
||||
static bool GroupHasDruidClass(Group* group) { return GroupHasClass(group, DRUID); }
|
||||
@@ -440,30 +470,39 @@ public:
|
||||
uint8 GetChanceToCastBySpellType(uint16 spellType);
|
||||
bool IsGroupPrimaryHealer();
|
||||
bool IsGroupPrimarySlower();
|
||||
bool IsBotCaster() { return (GetClass() == CLERIC || GetClass() == DRUID || GetClass() == SHAMAN || GetClass() == NECROMANCER || GetClass() == WIZARD || GetClass() == MAGICIAN || GetClass() == ENCHANTER); }
|
||||
bool IsBotINTCaster() { return (GetClass() == NECROMANCER || GetClass() == WIZARD || GetClass() == MAGICIAN || GetClass() == ENCHANTER); }
|
||||
bool IsBotWISCaster() { return (GetClass() == CLERIC || GetClass() == DRUID || GetClass() == SHAMAN); }
|
||||
bool IsBotCaster() { return IsCasterClass(GetClass()); }
|
||||
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
|
||||
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
|
||||
bool CanHeal();
|
||||
int GetRawACNoShield(int &shield_ac);
|
||||
void LoadAAs();
|
||||
uint32 GetAA(uint32 aa_id);
|
||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
||||
bool GetHasBeenSummoned() { return _hasBeenSummoned; }
|
||||
const glm::vec3 GetPreSummonLocation() const { return m_PreSummonLocation; }
|
||||
bool GetGroupMessagesOn() { return _groupMessagesOn; }
|
||||
bool GetInHealRotation() { return _isInHealRotation; }
|
||||
bool GetHealRotationActive() { return (GetInHealRotation() && _isHealRotationActive); }
|
||||
bool GetHealRotationUseFastHeals() { return _healRotationUseFastHeals; }
|
||||
bool GetHasHealedThisCycle() { return _hasHealedThisCycle; }
|
||||
Mob* GetHealRotationTarget();
|
||||
Mob* GetHealRotationTarget(uint8 index);
|
||||
Bot* GetHealRotationLeader();
|
||||
Bot* GetNextHealRotationMember();
|
||||
Bot* GetPrevHealRotationMember();
|
||||
uint8 GetNumHealRotationMembers () { return _numHealRotationMembers; }
|
||||
uint32 GetHealRotationNextHealTime() { return _healRotationNextHeal; }
|
||||
uint32 GetHealRotationTimer () { return _healRotationTimer; }
|
||||
bool GetBardUseOutOfCombatSongs() { return _bardUseOutOfCombatSongs;}
|
||||
|
||||
// new heal rotation code
|
||||
bool CreateHealRotation(uint32 cycle_duration_ms = 5000, bool fast_heals = false, bool adaptive_targeting = false, bool casting_override = false);
|
||||
bool DestroyHealRotation();
|
||||
bool JoinHealRotationMemberPool(std::shared_ptr<HealRotation>* heal_rotation);
|
||||
bool LeaveHealRotationMemberPool();
|
||||
|
||||
bool IsHealRotationMember() { return (m_member_of_heal_rotation.use_count() && m_member_of_heal_rotation.get()); }
|
||||
bool UseHealRotationFastHeals();
|
||||
bool UseHealRotationAdaptiveTargeting();
|
||||
|
||||
bool IsHealRotationActive();
|
||||
bool IsHealRotationReady();
|
||||
bool IsHealRotationCaster();
|
||||
bool HealRotationPokeTarget();
|
||||
Mob* HealRotationTarget();
|
||||
bool AdvanceHealRotation(bool use_interval = true);
|
||||
|
||||
bool IsMyHealRotationSet();
|
||||
bool AmICastingForHealRotation();
|
||||
void SetMyCastingForHealRotation(bool flag = true);
|
||||
|
||||
std::shared_ptr<HealRotation>* MemberOfHealRotation() { return &m_member_of_heal_rotation; }
|
||||
|
||||
bool GetAltOutOfCombatBehavior() { return _altoutofcombatbehavior;}
|
||||
bool GetShowHelm() { return _showhelm; }
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
inline virtual int32 GetSTR() const { return STR; }
|
||||
inline virtual int32 GetSTA() const { return STA; }
|
||||
@@ -530,42 +569,71 @@ public:
|
||||
// void SetBotOwnerCharacterID(uint32 botOwnerCharacterID) { _botOwnerCharacterID = botOwnerCharacterID; }
|
||||
void SetRangerAutoWeaponSelect(bool enable) { GetClass() == RANGER ? _rangerAutoWeaponSelect = enable : _rangerAutoWeaponSelect = false; }
|
||||
void SetBotRole(BotRoleType botRole) { _botRole = botRole; }
|
||||
void SetBotStance(BotStanceType botStance) { _botStance = botStance; }
|
||||
void SetBotStance(BotStanceType botStance) { _botStance = ((botStance != BotStanceUnknown) ? (botStance) : (BotStancePassive)); }
|
||||
void SetSpellRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetHasBeenSummoned(bool s);
|
||||
void SetPreSummonLocation(const glm::vec3& location) { m_PreSummonLocation = location; }
|
||||
void SetGroupMessagesOn(bool groupMessagesOn) { _groupMessagesOn = groupMessagesOn; }
|
||||
void SetInHealRotation( bool inRotation ) { _isInHealRotation = inRotation; }
|
||||
void SetHealRotationActive( bool isActive ) { _isHealRotationActive = isActive; }
|
||||
void SetHealRotationUseFastHeals( bool useFastHeals ) { _healRotationUseFastHeals = useFastHeals; }
|
||||
void SetHasHealedThisCycle( bool hasHealed ) { _hasHealedThisCycle = hasHealed; }
|
||||
void SetHealRotationLeader( Bot* leader );
|
||||
void SetNextHealRotationMember( Bot* healer );
|
||||
void SetPrevHealRotationMember( Bot* healer );
|
||||
void SetHealRotationNextHealTime( uint32 nextHealTime ) { _healRotationNextHeal = nextHealTime; }
|
||||
void SetHealRotationTimer( uint32 timer ) { _healRotationTimer = timer; }
|
||||
void SetNumHealRotationMembers( uint8 numMembers ) { _numHealRotationMembers = numMembers; }
|
||||
void SetBardUseOutOfCombatSongs(bool useOutOfCombatSongs) { _bardUseOutOfCombatSongs = useOutOfCombatSongs;}
|
||||
|
||||
void SetAltOutOfCombatBehavior(bool behavior_flag) { _altoutofcombatbehavior = behavior_flag;}
|
||||
void SetShowHelm(bool showhelm) { _showhelm = showhelm; }
|
||||
void SetBeardColor(uint8 value) { beardcolor = value; }
|
||||
void SetBeard(uint8 value) { beard = value; }
|
||||
void SetEyeColor1(uint8 value) { eyecolor1 = value; }
|
||||
void SetEyeColor2(uint8 value) { eyecolor2 = value; }
|
||||
void SetLuclinFace(uint8 value) { luclinface = value; }
|
||||
void SetHairColor(uint8 value) { haircolor = value; }
|
||||
void SetHairStyle(uint8 value) { hairstyle = value; }
|
||||
void SetDrakkinDetails(uint32 value) { drakkin_details = value; }
|
||||
void SetDrakkinHeritage(uint32 value) { drakkin_heritage = value; }
|
||||
void SetDrakkinTattoo(uint32 value) { drakkin_tattoo = value; }
|
||||
bool DyeArmor(int16 slot_id, uint32 rgb, bool all_flag = false, bool save_flag = true);
|
||||
|
||||
std::string CreateSayLink(Client* botOwner, const char* message, const char* name);
|
||||
|
||||
// Class Destructors
|
||||
virtual ~Bot();
|
||||
|
||||
// Publicized protected functions
|
||||
virtual void BotRangedAttack(Mob* other);
|
||||
|
||||
// Publicized private functions
|
||||
static NPCType FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack);
|
||||
void BotRemoveEquipItem(int slot);
|
||||
void RemoveBotItemBySlot(uint32 slotID, std::string* errorMessage);
|
||||
uint32 GetTotalPlayTime();
|
||||
|
||||
// New accessors for BotDatabase access
|
||||
bool DeleteBot();
|
||||
uint32* GetTimers() { return timers; }
|
||||
uint32 GetLastZoneID() { return _lastZoneId; }
|
||||
int32 GetBaseAC() { return _baseAC; }
|
||||
int32 GetBaseATK() { return _baseATK; }
|
||||
int32 GetBaseSTR() { return _baseSTR; }
|
||||
int32 GetBaseSTA() { return _baseSTA; }
|
||||
int32 GetBaseCHA() { return _baseCHA; }
|
||||
int32 GetBaseDEX() { return _baseDEX; }
|
||||
int32 GetBaseINT() { return _baseINT; }
|
||||
int32 GetBaseAGI() { return _baseAGI; }
|
||||
int32 GetBaseWIS() { return _baseWIS; }
|
||||
int32 GetBaseFR() { return _baseFR; }
|
||||
int32 GetBaseCR() { return _baseCR; }
|
||||
int32 GetBaseMR() { return _baseMR; }
|
||||
int32 GetBasePR() { return _basePR; }
|
||||
int32 GetBaseDR() { return _baseDR; }
|
||||
int32 GetBaseCorrup() { return _baseCorrup; }
|
||||
|
||||
protected:
|
||||
virtual void PetAIProcess();
|
||||
static NPCType FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack);
|
||||
virtual void BotMeditate(bool isSitting);
|
||||
virtual void BotRangedAttack(Mob* other);
|
||||
virtual bool CheckBotDoubleAttack(bool Triple = false);
|
||||
virtual int32 GetBotFocusEffect(BotfocusType bottype, uint16 spell_id);
|
||||
virtual int32 CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spell_id, bool best_focus=false);
|
||||
virtual int32 CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint16 spell_id);
|
||||
virtual int32 CalcBotAAFocus(BotfocusType type, uint32 aa_ID, uint32 points, uint16 spell_id);
|
||||
virtual void PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* client);
|
||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
virtual float GetMaxMeleeRangeToTarget(Mob* target);
|
||||
|
||||
static void SetBotGuildMembership(uint32 botId, uint32 guildid, uint8 rank);
|
||||
|
||||
private:
|
||||
// Class Members
|
||||
uint32 _botID;
|
||||
@@ -603,22 +671,14 @@ private:
|
||||
bool _hasBeenSummoned;
|
||||
glm::vec3 m_PreSummonLocation;
|
||||
uint8 _spellCastingChances[MaxStances][MaxSpellTypes];
|
||||
bool _groupMessagesOn;
|
||||
bool _isInHealRotation;
|
||||
bool _isHealRotationActive;
|
||||
bool _healRotationUseFastHeals;
|
||||
bool _hasHealedThisCycle;
|
||||
uint32 _healRotationTimer;
|
||||
uint32 _healRotationNextHeal;
|
||||
//char _healRotationTargets[MaxHealRotationTargets][64];
|
||||
uint16 _healRotationTargets[MaxHealRotationTargets];
|
||||
uint32 _healRotationLeader;
|
||||
uint32 _healRotationMemberNext;
|
||||
uint32 _healRotationMemberPrev;
|
||||
uint8 _numHealRotationMembers;
|
||||
|
||||
std::shared_ptr<HealRotation> m_member_of_heal_rotation;
|
||||
|
||||
std::map<uint32, BotAA> botAAs;
|
||||
InspectMessage_Struct _botInspectMessage;
|
||||
bool _bardUseOutOfCombatSongs;
|
||||
bool _altoutofcombatbehavior;
|
||||
bool _showhelm;
|
||||
bool _pauseAI;
|
||||
|
||||
// Private "base stats" Members
|
||||
int32 _baseMR;
|
||||
@@ -640,44 +700,25 @@ private:
|
||||
uint8 _baseGender; // Bots gender. Necessary to preserve the original value otherwise it can be changed by illusions.
|
||||
|
||||
// Class Methods
|
||||
void LoadAAs();
|
||||
int32 acmod();
|
||||
void GenerateBaseStats();
|
||||
void GenerateAppearance();
|
||||
void GenerateArmorClass();
|
||||
int32 GenerateBaseHitPoints();
|
||||
void GenerateAABonuses(StatBonuses* newbon);
|
||||
int32 GenerateBaseManaPoints();
|
||||
void GenerateSpecialAttacks();
|
||||
void SetBotID(uint32 botID);
|
||||
|
||||
// Private "Inventory" Methods
|
||||
void GetBotItems(std::string* errorMessage, Inventory &inv);
|
||||
void BotRemoveEquipItem(int slot);
|
||||
void GetBotItems(Inventory &inv, std::string* errorMessage);
|
||||
void BotAddEquipItem(int slot, uint32 id);
|
||||
uint32 GetBotItemBySlot(uint32 slotID);
|
||||
void RemoveBotItemBySlot(uint32 slotID, std::string* errorMessage);
|
||||
void SetBotItemInSlot(uint32 slotID, uint32 itemID, const ItemInst* inst, std::string* errorMessage);
|
||||
uint32 GetBotItemsCount(std::string* errorMessage);
|
||||
uint32 GetTotalPlayTime();
|
||||
void SaveBuffs(); // Saves existing buffs to the database to persist zoning and camping
|
||||
void LoadBuffs(); // Retrieves saved buffs from the database on spawning
|
||||
void LoadPetBuffs(SpellBuff_Struct* petBuffs, uint32 botPetSaveId);
|
||||
void SavePetBuffs(SpellBuff_Struct* petBuffs, uint32 botPetSaveId);
|
||||
void LoadPetItems(uint32* petItems, uint32 botPetSaveId);
|
||||
void SavePetItems(uint32* petItems, uint32 botPetSaveId);
|
||||
void LoadPetStats(std::string* petName, uint32* petMana, uint32* petHitPoints, uint32* botPetId, uint32 botPetSaveId);
|
||||
uint32 SavePetStats(std::string petName, uint32 petMana, uint32 petHitPoints, uint32 botPetId);
|
||||
void LoadPet(); // Load and spawn bot pet if there is one
|
||||
void SavePet(); // Save and depop bot pet if there is one
|
||||
uint32 GetPetSaveId();
|
||||
void DeletePetBuffs(uint32 botPetSaveId);
|
||||
void DeletePetItems(uint32 botPetSaveId);
|
||||
void DeletePetStats(uint32 botPetSaveId);
|
||||
void LoadGuildMembership(uint32* guildId, uint8* guildRank, std::string* guildName);
|
||||
void LoadStance();
|
||||
void SaveStance();
|
||||
void LoadTimers();
|
||||
void SaveTimers();
|
||||
|
||||
// Private "Pet" Methods
|
||||
bool LoadPet(); // Load and spawn bot pet if there is one
|
||||
bool SavePet(); // Save and depop bot pet if there is one
|
||||
bool DeletePet();
|
||||
};
|
||||
|
||||
#endif // BOTS
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,676 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 BOT_COMMAND_H
|
||||
#define BOT_COMMAND_H
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
class Client;
|
||||
class Seperator;
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "bot.h"
|
||||
|
||||
|
||||
class BCEnum
|
||||
{
|
||||
public:
|
||||
typedef enum SpellType {
|
||||
SpT_None = 0,
|
||||
SpT_BindAffinity,
|
||||
SpT_Charm,
|
||||
SpT_Cure,
|
||||
SpT_Depart,
|
||||
SpT_Escape,
|
||||
SpT_Identify,
|
||||
SpT_Invisibility,
|
||||
SpT_Levitation,
|
||||
SpT_Lull,
|
||||
SpT_Mesmerize,
|
||||
SpT_MovementSpeed,
|
||||
SpT_Resistance,
|
||||
SpT_Resurrect,
|
||||
SpT_Rune,
|
||||
SpT_SendHome,
|
||||
SpT_Size,
|
||||
SpT_Stance,
|
||||
SpT_SummonCorpse,
|
||||
SpT_WaterBreathing
|
||||
} SpType;
|
||||
static const int SpellTypeFirst = SpT_BindAffinity;
|
||||
static const int SpellTypeLast = SpT_WaterBreathing;
|
||||
|
||||
typedef enum TargetType {
|
||||
TT_None = 0,
|
||||
TT_Corpse,
|
||||
TT_Self,
|
||||
TT_Animal,
|
||||
TT_Undead,
|
||||
TT_Summoned,
|
||||
TT_Plant,
|
||||
TT_Single,
|
||||
TT_GroupV1,
|
||||
TT_GroupV2,
|
||||
TT_AECaster,
|
||||
TT_AEBard,
|
||||
TT_AETarget
|
||||
} TType;
|
||||
static const int TargetTypeFirst = TT_Corpse;
|
||||
static const int TargetTypeLast = TT_AETarget;
|
||||
static const int TargetTypeCount = 13;
|
||||
|
||||
typedef enum TargetMask {
|
||||
TM_None = 0,
|
||||
TM_Corpse = 1,
|
||||
TM_Self = 2,
|
||||
TM_Animal = 4,
|
||||
TM_Undead = 8,
|
||||
TM_Summoned = 16,
|
||||
TM_Plant = 32,
|
||||
TM_Single = 124, // currently, 2^6 + 2^{2..5}) -or- (64+32+16+8+4)
|
||||
TM_GroupV1 = 128,
|
||||
TM_GroupV2 = 256,
|
||||
TM_AECaster = 512,
|
||||
TM_AEBard = 1024,
|
||||
TM_AETarget = 2048
|
||||
} TMask;
|
||||
|
||||
typedef enum AppearanceFailType {
|
||||
AFT_None = 0,
|
||||
AFT_Value,
|
||||
AFT_GenderRace,
|
||||
AFT_Race
|
||||
} AFType;
|
||||
|
||||
typedef enum AilmentType {
|
||||
AT_None = 0,
|
||||
AT_Blindness, // SE: 20
|
||||
AT_Disease, // SE: 35
|
||||
AT_Poison, // SE: 36
|
||||
AT_Curse, // SE: 116
|
||||
AT_Corruption // SE: 369
|
||||
} AType;
|
||||
static const int AilmentTypeCount = 5;
|
||||
|
||||
typedef enum InvisibilityType {
|
||||
IT_None = 0,
|
||||
IT_Animal,
|
||||
IT_Undead,
|
||||
IT_Living,
|
||||
IT_See
|
||||
} IType;
|
||||
|
||||
typedef enum ResistanceType {
|
||||
RT_None = 0,
|
||||
RT_Fire, // SE: 46
|
||||
RT_Cold, // SE: 47
|
||||
RT_Poison, // SE: 48
|
||||
RT_Disease, // SE: 49
|
||||
RT_Magic, // SE: 50
|
||||
RT_Corruption // SE: 370
|
||||
} RType;
|
||||
static const int ResistanceTypeCount = 6;
|
||||
|
||||
typedef enum SizeType {
|
||||
SzT_None = 0,
|
||||
SzT_Enlarge,
|
||||
SzT_Reduce
|
||||
} SzType;
|
||||
|
||||
typedef enum StanceType {
|
||||
StT_None = 0,
|
||||
StT_Aggressive,
|
||||
StT_Defensive
|
||||
} StType;
|
||||
|
||||
static std::string SpellTypeEnumToString(BCEnum::SpType spell_type) {
|
||||
switch (spell_type) {
|
||||
case SpT_BindAffinity:
|
||||
return "SpT_BindAffinity";
|
||||
case SpT_Charm:
|
||||
return "SpT_Charm";
|
||||
case SpT_Cure:
|
||||
return "SpT_Cure";
|
||||
case SpT_Depart:
|
||||
return "SpT_Depart";
|
||||
case SpT_Escape:
|
||||
return "SpT_Escape";
|
||||
case SpT_Identify:
|
||||
return "SpT_Identify";
|
||||
case SpT_Invisibility:
|
||||
return "SpT_Invisibility";
|
||||
case SpT_Levitation:
|
||||
return "SpT_Levitation";
|
||||
case SpT_Lull:
|
||||
return "SpT_Lull";
|
||||
case SpT_Mesmerize:
|
||||
return "SpT_Mesmerize";
|
||||
case SpT_MovementSpeed:
|
||||
return "SpT_MovementSpeed";
|
||||
case SpT_Resistance:
|
||||
return "SpT_Resistance";
|
||||
case SpT_Resurrect:
|
||||
return "SpT_Resurrect";
|
||||
case SpT_Rune:
|
||||
return "SpT_Rune";
|
||||
case SpT_SendHome:
|
||||
return "SpT_SendHome";
|
||||
case SpT_Size:
|
||||
return "SpT_Size";
|
||||
case SpT_Stance:
|
||||
return "SpT_Stance";
|
||||
case SpT_SummonCorpse:
|
||||
return "SpT_SummonCorpse";
|
||||
case SpT_WaterBreathing:
|
||||
return "SpT_WaterBreathing";
|
||||
default:
|
||||
return "SpT_None";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string TargetTypeEnumToString(BCEnum::TType target_type) {
|
||||
switch (target_type) {
|
||||
case TT_Self:
|
||||
return "TT_Self";
|
||||
case TT_Animal:
|
||||
return "TT_Animal";
|
||||
case TT_Undead:
|
||||
return "TT_Undead";
|
||||
case TT_Summoned:
|
||||
return "TT_Summoned";
|
||||
case TT_Plant:
|
||||
return "TT_Plant";
|
||||
case TT_Single:
|
||||
return "TT_Single";
|
||||
case TT_GroupV1:
|
||||
return "TT_GroupV1";
|
||||
case TT_GroupV2:
|
||||
return "TT_GroupV2";
|
||||
case TT_AECaster:
|
||||
return "TT_AECaster";
|
||||
case TT_AEBard:
|
||||
return "TT_AEBard";
|
||||
case TT_AETarget:
|
||||
return "TT_AETarget";
|
||||
case TT_Corpse:
|
||||
return "TT_Corpse";
|
||||
default:
|
||||
return "TT_None";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class STBaseEntry;
|
||||
class STCharmEntry;
|
||||
class STCureEntry;
|
||||
class STDepartEntry;
|
||||
class STEscapeEntry;
|
||||
class STInvisibilityEntry;
|
||||
class STMovementSpeedEntry;
|
||||
class STResistanceEntry;
|
||||
class STResurrectEntry;
|
||||
class STSendHomeEntry;
|
||||
class STSizeEntry;
|
||||
class STStanceEntry;
|
||||
|
||||
class STBaseEntry
|
||||
{
|
||||
protected:
|
||||
BCEnum::SpType m_bcst;
|
||||
|
||||
public:
|
||||
int spell_id;
|
||||
uint8 spell_level;
|
||||
uint8 caster_class;
|
||||
BCEnum::TType target_type;
|
||||
|
||||
// A non-polymorphic constructor requires an appropriate, non-'ST_None' BCEnum::SType
|
||||
STBaseEntry(BCEnum::SpType init_bcst = BCEnum::SpT_None) {
|
||||
spell_id = 0;
|
||||
spell_level = 255;
|
||||
caster_class = 255;
|
||||
target_type = BCEnum::TT_None;
|
||||
m_bcst = init_bcst;
|
||||
}
|
||||
STBaseEntry(STBaseEntry* prototype) {
|
||||
spell_id = prototype->spell_id;
|
||||
spell_level = 255;
|
||||
caster_class = 255;
|
||||
target_type = prototype->target_type;
|
||||
m_bcst = prototype->BCST();
|
||||
}
|
||||
virtual ~STBaseEntry() { return; };
|
||||
|
||||
BCEnum::SpType BCST() { return m_bcst; }
|
||||
|
||||
virtual bool IsDerived() { return false; }
|
||||
|
||||
bool IsCharm() const { return (m_bcst == BCEnum::SpT_Charm); }
|
||||
bool IsCure() const { return (m_bcst == BCEnum::SpT_Cure); }
|
||||
bool IsDepart() const { return (m_bcst == BCEnum::SpT_Depart); }
|
||||
bool IsEscape() const { return (m_bcst == BCEnum::SpT_Escape); }
|
||||
bool IsInvisibility() const { return (m_bcst == BCEnum::SpT_Invisibility); }
|
||||
bool IsMovementSpeed() const { return (m_bcst == BCEnum::SpT_MovementSpeed); }
|
||||
bool IsResistance() const { return (m_bcst == BCEnum::SpT_Resistance); }
|
||||
bool IsResurrect() const { return (m_bcst == BCEnum::SpT_Resurrect); }
|
||||
bool IsSendHome() const { return (m_bcst == BCEnum::SpT_SendHome); }
|
||||
bool IsSize() const { return (m_bcst == BCEnum::SpT_Size); }
|
||||
bool IsStance() const { return (m_bcst == BCEnum::SpT_Stance); }
|
||||
|
||||
virtual STCharmEntry* SafeCastToCharm() { return nullptr; }
|
||||
virtual STCureEntry* SafeCastToCure() { return nullptr; }
|
||||
virtual STDepartEntry* SafeCastToDepart() { return nullptr; }
|
||||
virtual STEscapeEntry* SafeCastToEscape() { return nullptr; }
|
||||
virtual STInvisibilityEntry* SafeCastToInvisibility() { return nullptr; }
|
||||
virtual STMovementSpeedEntry* SafeCastToMovementSpeed() { return nullptr; }
|
||||
virtual STResistanceEntry* SafeCastToResistance() { return nullptr; }
|
||||
virtual STResurrectEntry* SafeCastToResurrect() { return nullptr; }
|
||||
virtual STSendHomeEntry* SafeCastToSendHome() { return nullptr; }
|
||||
virtual STSizeEntry* SafeCastToSize() { return nullptr; }
|
||||
virtual STStanceEntry* SafeCastToStance() { return nullptr; }
|
||||
};
|
||||
|
||||
class STCharmEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
bool dire;
|
||||
|
||||
STCharmEntry() {
|
||||
m_bcst = BCEnum::SpT_Charm;
|
||||
dire = false;
|
||||
}
|
||||
STCharmEntry(STCharmEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Charm;
|
||||
dire = prototype->dire;
|
||||
}
|
||||
virtual ~STCharmEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STCharmEntry* SafeCastToCharm() { return ((m_bcst == BCEnum::SpT_Charm) ? (static_cast<STCharmEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STCureEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
int cure_value[BCEnum::AilmentTypeCount];
|
||||
int cure_total;
|
||||
|
||||
STCureEntry() {
|
||||
m_bcst = BCEnum::SpT_Cure;
|
||||
memset(&cure_value, 0, (sizeof(int) * BCEnum::AilmentTypeCount));
|
||||
cure_total = 0;
|
||||
}
|
||||
STCureEntry(STCureEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Cure;
|
||||
memcpy(&cure_value, prototype->cure_value, (sizeof(int) * BCEnum::AilmentTypeCount));
|
||||
cure_total = prototype->cure_total;
|
||||
}
|
||||
virtual ~STCureEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STCureEntry* SafeCastToCure() { return ((m_bcst == BCEnum::SpT_Cure) ? (static_cast<STCureEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STDepartEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
bool single;
|
||||
std::string long_name;
|
||||
|
||||
STDepartEntry() {
|
||||
m_bcst = BCEnum::SpT_Depart;
|
||||
single = false;
|
||||
long_name.clear();
|
||||
}
|
||||
STDepartEntry(STDepartEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Depart;
|
||||
single = prototype->single;
|
||||
long_name = prototype->long_name;
|
||||
}
|
||||
virtual ~STDepartEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STDepartEntry* SafeCastToDepart() { return ((m_bcst == BCEnum::SpT_Depart) ? (static_cast<STDepartEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STEscapeEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
bool lesser;
|
||||
|
||||
STEscapeEntry() {
|
||||
m_bcst = BCEnum::SpT_Escape;
|
||||
lesser = false;
|
||||
}
|
||||
STEscapeEntry(STEscapeEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Escape;
|
||||
lesser = prototype->lesser;
|
||||
}
|
||||
virtual ~STEscapeEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STEscapeEntry* SafeCastToEscape() { return ((m_bcst == BCEnum::SpT_Escape) ? (static_cast<STEscapeEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STInvisibilityEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
BCEnum::IType invis_type;
|
||||
|
||||
STInvisibilityEntry() {
|
||||
m_bcst = BCEnum::SpT_Invisibility;
|
||||
invis_type = BCEnum::IT_None;
|
||||
}
|
||||
STInvisibilityEntry(STInvisibilityEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Invisibility;
|
||||
invis_type = prototype->invis_type;
|
||||
}
|
||||
virtual ~STInvisibilityEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STInvisibilityEntry* SafeCastToInvisibility() { return ((m_bcst == BCEnum::SpT_Invisibility) ? (static_cast<STInvisibilityEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STMovementSpeedEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
bool group;
|
||||
|
||||
STMovementSpeedEntry() {
|
||||
m_bcst = BCEnum::SpT_MovementSpeed;
|
||||
group = false;
|
||||
}
|
||||
STMovementSpeedEntry(STMovementSpeedEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_MovementSpeed;
|
||||
group = prototype->group;
|
||||
}
|
||||
virtual ~STMovementSpeedEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STMovementSpeedEntry* SafeCastToMovementSpeed() { return ((m_bcst == BCEnum::SpT_MovementSpeed) ? (static_cast<STMovementSpeedEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STResistanceEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
int resist_value[BCEnum::ResistanceTypeCount];
|
||||
int resist_total;
|
||||
|
||||
STResistanceEntry() {
|
||||
m_bcst = BCEnum::SpT_Resistance;
|
||||
memset(&resist_value, 0, (sizeof(int) * BCEnum::ResistanceTypeCount));
|
||||
resist_total = 0;
|
||||
}
|
||||
STResistanceEntry(STResistanceEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Resistance;
|
||||
memcpy(&resist_value, prototype->resist_value, (sizeof(int) * BCEnum::ResistanceTypeCount));
|
||||
resist_total = prototype->resist_total;
|
||||
}
|
||||
virtual ~STResistanceEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STResistanceEntry* SafeCastToResistance() { return ((m_bcst == BCEnum::SpT_Resistance) ? (static_cast<STResistanceEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STResurrectEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
bool aoe;
|
||||
|
||||
STResurrectEntry() {
|
||||
m_bcst = BCEnum::SpT_Resurrect;
|
||||
aoe = false;
|
||||
}
|
||||
STResurrectEntry(STResurrectEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Resurrect;
|
||||
aoe = prototype->aoe;
|
||||
}
|
||||
virtual ~STResurrectEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STResurrectEntry* SafeCastToResurrect() { return ((m_bcst == BCEnum::SpT_Resurrect) ? (static_cast<STResurrectEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STSendHomeEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
bool group;
|
||||
|
||||
STSendHomeEntry() {
|
||||
m_bcst = BCEnum::SpT_SendHome;
|
||||
group = false;
|
||||
}
|
||||
STSendHomeEntry(STSendHomeEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_SendHome;
|
||||
group = prototype->group;
|
||||
}
|
||||
virtual ~STSendHomeEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STSendHomeEntry* SafeCastToSendHome() { return ((m_bcst == BCEnum::SpT_SendHome) ? (static_cast<STSendHomeEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STSizeEntry : public STBaseEntry
|
||||
{
|
||||
public:
|
||||
BCEnum::SzType size_type;
|
||||
|
||||
STSizeEntry() {
|
||||
m_bcst = BCEnum::SpT_Size;
|
||||
size_type = BCEnum::SzT_None;
|
||||
}
|
||||
STSizeEntry(STSizeEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Size;
|
||||
size_type = prototype->size_type;
|
||||
}
|
||||
virtual ~STSizeEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STSizeEntry* SafeCastToSize() { return ((m_bcst == BCEnum::SpT_Size) ? (static_cast<STSizeEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
class STStanceEntry : public STBaseEntry {
|
||||
public:
|
||||
BCEnum::StType stance_type;
|
||||
|
||||
STStanceEntry() {
|
||||
m_bcst = BCEnum::SpT_Stance;
|
||||
stance_type = BCEnum::StT_None;
|
||||
}
|
||||
STStanceEntry(STStanceEntry* prototype) : STBaseEntry(prototype) {
|
||||
m_bcst = BCEnum::SpT_Stance;
|
||||
stance_type = prototype->stance_type;
|
||||
}
|
||||
virtual ~STStanceEntry() { return; };
|
||||
|
||||
virtual bool IsDerived() { return true; }
|
||||
|
||||
virtual STStanceEntry* SafeCastToStance() { return ((m_bcst == BCEnum::SpT_Stance) ? (static_cast<STStanceEntry*>(this)) : (nullptr)); }
|
||||
};
|
||||
|
||||
|
||||
typedef std::list<STBaseEntry*> bcst_list;
|
||||
typedef std::map<BCEnum::SpType, bcst_list> bcst_map;
|
||||
|
||||
typedef std::map<BCEnum::SpType, std::string> bcst_required_bot_classes_map;
|
||||
typedef std::map<BCEnum::SpType, std::map<uint8, std::string>> bcst_required_bot_classes_map_by_class;
|
||||
|
||||
typedef std::map<uint8, uint8> bcst_levels;
|
||||
typedef std::map<BCEnum::SpType, bcst_levels> bcst_levels_map;
|
||||
|
||||
|
||||
#define BOT_COMMAND_CHAR '^'
|
||||
|
||||
typedef void (*BotCmdFuncPtr)(Client *,const Seperator *);
|
||||
|
||||
typedef struct {
|
||||
int access;
|
||||
const char *desc; // description of bot command
|
||||
BotCmdFuncPtr function; // null means perl function
|
||||
} BotCommandRecord;
|
||||
|
||||
extern int (*bot_command_dispatch)(Client *,char const*);
|
||||
extern int bot_command_count; // number of bot commands loaded
|
||||
|
||||
|
||||
// the bot command system:
|
||||
int bot_command_init(void);
|
||||
void bot_command_deinit(void);
|
||||
int bot_command_add(std::string bot_command_name, const char *desc, int access, BotCmdFuncPtr function);
|
||||
int bot_command_not_avail(Client *c, const char *message);
|
||||
int bot_command_real_dispatch(Client *c, char const *message);
|
||||
void bot_command_log_command(Client *c, const char *message);
|
||||
|
||||
|
||||
// bot commands
|
||||
void bot_command_actionable(Client *c, const Seperator *sep);
|
||||
void bot_command_aggressive(Client *c, const Seperator *sep);
|
||||
void bot_command_attack(Client *c, const Seperator *sep);
|
||||
void bot_command_bind_affinity(Client *c, const Seperator *sep);
|
||||
void bot_command_bot(Client *c, const Seperator *sep);
|
||||
void bot_command_botgroup(Client *c, const Seperator *sep);
|
||||
void bot_command_charm(Client *c, const Seperator *sep);
|
||||
void bot_command_cure(Client *c, const Seperator *sep);
|
||||
void bot_command_defensive(Client *c, const Seperator *sep);
|
||||
void bot_command_depart(Client *c, const Seperator *sep);
|
||||
void bot_command_escape(Client *c, const Seperator *sep);
|
||||
void bot_command_find_aliases(Client *c, const Seperator *sep);
|
||||
void bot_command_follow(Client *c, const Seperator *sep);
|
||||
void bot_command_guard(Client *c, const Seperator *sep);
|
||||
void bot_command_heal_rotation(Client *c, const Seperator *sep);
|
||||
void bot_command_help(Client *c, const Seperator *sep);
|
||||
void bot_command_hold(Client *c, const Seperator *sep);
|
||||
void bot_command_identify(Client *c, const Seperator *sep);
|
||||
void bot_command_inventory(Client *c, const Seperator *sep);
|
||||
void bot_command_invisibility(Client *c, const Seperator *sep);
|
||||
void bot_command_levitation(Client *c, const Seperator *sep);
|
||||
void bot_command_lull(Client *c, const Seperator *sep);
|
||||
void bot_command_mesmerize(Client *c, const Seperator *sep);
|
||||
void bot_command_movement_speed(Client *c, const Seperator *sep);
|
||||
void bot_command_pet(Client *c, const Seperator *sep);
|
||||
void bot_command_pick_lock(Client *c, const Seperator *sep);
|
||||
void bot_command_pull(Client *c, const Seperator *sep);
|
||||
void bot_command_release(Client *c, const Seperator *sep);
|
||||
void bot_command_resistance(Client *c, const Seperator *sep);
|
||||
void bot_command_resurrect(Client *c, const Seperator *sep);
|
||||
void bot_command_rune(Client *c, const Seperator *sep);
|
||||
void bot_command_send_home(Client *c, const Seperator *sep);
|
||||
void bot_command_size(Client *c, const Seperator *sep);
|
||||
void bot_command_summon_corpse(Client *c, const Seperator *sep);
|
||||
void bot_command_taunt(Client *c, const Seperator *sep);
|
||||
void bot_command_track(Client *c, const Seperator *sep);
|
||||
void bot_command_water_breathing(Client *c, const Seperator *sep);
|
||||
|
||||
|
||||
// bot subcommands
|
||||
void bot_subcommand_bot_appearance(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_beard_color(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_beard_style(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_camp(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_clone(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_create(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_delete(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_details(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_eyes(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_face(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_hair_color(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_hairstyle(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_heritage(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_inspect_message(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_list(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_out_of_combat(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_report(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_spawn(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_stance(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_summon(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_tattoo(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_toggle_archer(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_update(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_bot_woad(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_botgroup_create(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_botgroup_list(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_botgroup_load(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_botgroup_remove_member(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_circle(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_evacuate(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_adaptive_targeting(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_add_member(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_add_target(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_adjust_critical(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_adjust_safe(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_casting_override(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_change_interval(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_clear_hot(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_clear_targets(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_create(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_delete(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_fast_heals(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_list(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_remove_member(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_remove_target(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_reset_limits(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_save(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_set_hot(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_start(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_heal_rotation_stop(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_give(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_list(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_remove(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_window(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_pet_remove(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_pet_set_type(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_portal(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_succor(Client *c, const Seperator *sep);
|
||||
|
||||
|
||||
// bot command helpers
|
||||
bool helper_bot_appearance_fail(Client *bot_owner, Bot *my_bot, BCEnum::AFType fail_type, const char* type_desc);
|
||||
void helper_bot_appearance_form_final(Client *bot_owner, Bot *my_bot);
|
||||
void helper_bot_appearance_form_update(Bot *my_bot);
|
||||
uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_class, uint16 bot_race, uint8 bot_gender);
|
||||
void helper_bot_out_of_combat(Client *bot_owner, Bot *my_bot);
|
||||
bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id, bool annouce_cast = true, uint32* dont_root_before = nullptr);
|
||||
bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, const char *alias, const char *command);
|
||||
void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_bot, bcst_list* local_list, bool single_flag = false);
|
||||
bool helper_is_help_or_usage(const char* arg);
|
||||
bool helper_no_available_bots(Client *bot_owner, Bot *my_bot = nullptr);
|
||||
void helper_send_available_subcommands(Client *bot_owner, const char* command_simile, const std::list<const char*>& subcommand_list);
|
||||
void helper_send_usage_required_bots(Client *bot_owner, BCEnum::SpType spell_type, uint8 bot_class = 0);
|
||||
bool helper_spell_check_fail(STBaseEntry* local_entry);
|
||||
bool helper_spell_list_fail(Client *bot_owner, bcst_list* spell_list, BCEnum::SpType spell_type);
|
||||
#endif
|
||||
|
||||
#endif // BOTS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,291 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 BOT_DATABASE_H
|
||||
#define BOT_DATABASE_H
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
#include "../common/dbcore.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class Bot;
|
||||
class ItemInst;
|
||||
class Inventory;
|
||||
struct BotsAvailableList;
|
||||
|
||||
|
||||
class BotDatabase : public DBcore
|
||||
{
|
||||
public:
|
||||
BotDatabase();
|
||||
BotDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
|
||||
virtual ~BotDatabase();
|
||||
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
|
||||
|
||||
bool LoadBotCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &bot_command_settings);
|
||||
|
||||
|
||||
/* Bot functions */
|
||||
bool QueryNameAvailablity(const std::string& bot_name, bool& available_flag);
|
||||
bool QueryBotCount(const uint32 owner_id, uint32& bot_count);
|
||||
bool LoadQuestableSpawnCount(const uint32 owner_id, int& spawn_count);
|
||||
bool LoadBotsList(const uint32 owner_id, std::list<BotsAvailableList>& bots_list);
|
||||
|
||||
bool LoadOwnerID(const std::string& bot_name, uint32& owner_id);
|
||||
bool LoadOwnerID(const uint32 bot_id, uint32& owner_id);
|
||||
bool LoadBotID(const uint32 owner_id, const std::string& bot_name, uint32& bot_id);
|
||||
|
||||
bool LoadBot(const uint32 bot_id, Bot*& loaded_bot);
|
||||
bool SaveNewBot(Bot* bot_inst, uint32& bot_id);
|
||||
bool SaveBot(Bot* bot_inst);
|
||||
bool DeleteBot(const uint32 bot_id);
|
||||
|
||||
bool LoadBuffs(Bot* bot_inst);
|
||||
bool SaveBuffs(Bot* bot_inst);
|
||||
bool DeleteBuffs(const uint32 bot_id);
|
||||
|
||||
bool LoadStance(const uint32 bot_id, int& bot_stance);
|
||||
bool LoadStance(Bot* bot_inst, bool& stance_flag);
|
||||
bool SaveStance(const uint32 bot_id, const int bot_stance);
|
||||
bool SaveStance(Bot* bot_inst);
|
||||
bool DeleteStance(const uint32 bot_id);
|
||||
|
||||
bool LoadTimers(Bot* bot_inst);
|
||||
bool SaveTimers(Bot* bot_inst);
|
||||
bool DeleteTimers(const uint32 bot_id);
|
||||
|
||||
bool LoadGuildMembership(const uint32 bot_id, uint32& guild_id, uint8& guild_rank, std::string& guild_name);
|
||||
bool SaveGuildMembership(const uint32 bot_id, const uint32 guild_id, const uint8 guild_rank);
|
||||
bool DeleteGuildMembership(const uint32 bot_id);
|
||||
|
||||
|
||||
/* Bot inventory functions */
|
||||
bool QueryInventoryCount(const uint32 bot_id, uint32& item_count);
|
||||
|
||||
bool LoadItems(const uint32 bot_id, Inventory &inventory_inst);
|
||||
bool SaveItems(Bot* bot_inst);
|
||||
bool DeleteItems(const uint32 bot_id);
|
||||
|
||||
bool LoadItemBySlot(Bot* bot_inst);
|
||||
bool LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint32& item_id);
|
||||
bool SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const ItemInst* item_inst);
|
||||
bool DeleteItemBySlot(const uint32 bot_id, const uint32 slot_id);
|
||||
|
||||
bool LoadEquipmentColor(const uint32 bot_id, const uint8 material_slot_id, uint32& rgb);
|
||||
bool SaveEquipmentColor(const uint32 bot_id, const int16 slot_id, const uint32 rgb);
|
||||
|
||||
|
||||
/* Bot pet functions */
|
||||
bool LoadPetIndex(const uint32 bot_id, uint32& pet_index);
|
||||
bool LoadPetSpellID(const uint32 bot_id, uint32& pet_spell_id);
|
||||
|
||||
bool LoadPetStats(const uint32 bot_id, std::string& pet_name, uint32& pet_mana, uint32& pet_hp, uint32& pet_spell_id);
|
||||
bool SavePetStats(const uint32 bot_id, const std::string& pet_name, const uint32 pet_mana, const uint32 pet_hp, const uint32 pet_spell_id);
|
||||
bool DeletePetStats(const uint32 bot_id);
|
||||
|
||||
bool LoadPetBuffs(const uint32 bot_id, SpellBuff_Struct* pet_buffs);
|
||||
bool SavePetBuffs(const uint32 bot_id, const SpellBuff_Struct* pet_buffs, bool delete_flag = false);
|
||||
bool DeletePetBuffs(const uint32 bot_id);
|
||||
|
||||
bool LoadPetItems(const uint32 bot_id, uint32* pet_items);
|
||||
bool SavePetItems(const uint32 bot_id, const uint32* pet_items, bool delete_flag = false);
|
||||
bool DeletePetItems(const uint32 bot_id);
|
||||
|
||||
|
||||
/* Bot command functions */
|
||||
bool LoadInspectMessage(const uint32 bot_id, InspectMessage_Struct& inspect_message);
|
||||
bool SaveInspectMessage(const uint32 bot_id, const InspectMessage_Struct& inspect_message);
|
||||
bool DeleteInspectMessage(const uint32 bot_id);
|
||||
|
||||
bool SaveAllInspectMessages(const uint32 owner_id, const InspectMessage_Struct& inspect_message);
|
||||
bool DeleteAllInspectMessages(const uint32 owner_id);
|
||||
|
||||
bool SaveAllArmorColorBySlot(const uint32 owner_id, const int16 slot_id, const uint32 rgb_value);
|
||||
bool SaveAllArmorColors(const uint32 owner_id, const uint32 rgb_value);
|
||||
|
||||
bool SaveHelmAppearance(const uint32 owner_id, const uint32 bot_id, const bool show_flag = true);
|
||||
bool SaveAllHelmAppearances(const uint32 owner_id, const bool show_flag = true);
|
||||
|
||||
bool ToggleHelmAppearance(const uint32 owner_id, const uint32 bot_id);
|
||||
bool ToggleAllHelmAppearances(const uint32 owner_id);
|
||||
|
||||
bool SaveFollowDistance(const uint32 owner_id, const uint32 bot_id, const uint32 follow_distance);
|
||||
bool SaveAllFollowDistances(const uint32 owner_id, const uint32 follow_distance);
|
||||
|
||||
bool CreateCloneBot(const uint32 owner_id, const uint32 bot_id, const std::string& clone_name, uint32& clone_id);
|
||||
bool CreateCloneBotInventory(const uint32 owner_id, const uint32 bot_id, const uint32 clone_id);
|
||||
|
||||
|
||||
/* Bot bot-group functions */
|
||||
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);
|
||||
|
||||
bool LoadBotGroupIDByBotGroupName(const std::string& botgroup_name, uint32& botgroup_id);
|
||||
bool LoadBotGroupIDByLeaderID(const uint32 leader_id, uint32& botgroup_id);
|
||||
bool LoadBotGroupIDByMemberID(const uint32 member_id, uint32& botgroup_id);
|
||||
|
||||
bool LoadLeaderIDByBotGroupName(const std::string& botgroup_name, uint32& leader_id);
|
||||
bool LoadLeaderIDByBotGroupID(const uint32 botgroup_id, uint32& leader_id);
|
||||
|
||||
bool LoadBotGroupNameByBotGroupID(const uint32 botgroup_id, std::string& botgroup_name);
|
||||
bool LoadBotGroupNameByLeaderID(const uint32 leader_id, std::string& botgroup_name);
|
||||
|
||||
bool CreateBotGroup(const std::string& botgroup_name, const uint32 leader_id);
|
||||
bool DeleteBotGroup(const uint32 leader_id);
|
||||
bool AddMemberToBotGroup(const uint32 leader_id, const uint32 member_id);
|
||||
bool RemoveMemberFromBotGroup(const uint32 member_id);
|
||||
|
||||
bool LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, const std::string& botgroup_name, uint32& botgroup_id);
|
||||
bool LoadBotGroup(const std::string& botgroup_name, std::map<uint32, std::list<uint32>>& member_list);
|
||||
|
||||
bool LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, std::string>>& botgroups_list);
|
||||
|
||||
|
||||
/* Bot group functions */
|
||||
bool LoadGroupedBotsByGroupID(const uint32 group_id, std::list<uint32>& group_list);
|
||||
|
||||
|
||||
/* Bot heal rotation functions */
|
||||
bool LoadHealRotationIDByBotID(const uint32 bot_id, uint32& hr_index);
|
||||
|
||||
bool LoadHealRotation(Bot* hr_member, std::list<uint32>& member_list, std::list<std::string>& target_list, bool& load_flag, bool& member_fail, bool& target_fail);
|
||||
bool LoadHealRotationMembers(const uint32 hr_index, std::list<uint32>& member_list);
|
||||
bool LoadHealRotationTargets(const uint32 hr_index, std::list<std::string>& target_list);
|
||||
bool SaveHealRotation(Bot* hr_member, bool& member_fail, bool& target_fail);
|
||||
bool DeleteHealRotation(const uint32 creator_id);
|
||||
|
||||
bool DeleteAllHealRotations(const uint32 owner_id);
|
||||
|
||||
/* Bot miscellaneous functions */
|
||||
|
||||
|
||||
class fail {
|
||||
public:
|
||||
/* fail::Bot functions */
|
||||
static const char* QueryNameAvailablity();
|
||||
static const char* QueryBotCount();
|
||||
static const char* LoadQuestableSpawnCount();
|
||||
static const char* LoadBotsList();
|
||||
static const char* LoadOwnerID();
|
||||
static const char* LoadBotID();
|
||||
static const char* LoadBot();
|
||||
static const char* SaveNewBot();
|
||||
static const char* SaveBot();
|
||||
static const char* DeleteBot();
|
||||
static const char* LoadBuffs();
|
||||
static const char* SaveBuffs();
|
||||
static const char* DeleteBuffs();
|
||||
static const char* LoadStance();
|
||||
static const char* SaveStance();
|
||||
static const char* DeleteStance();
|
||||
static const char* LoadTimers();
|
||||
static const char* SaveTimers();
|
||||
static const char* DeleteTimers();
|
||||
static const char* LoadGuildMembership();
|
||||
static const char* SaveGuildMembership();
|
||||
static const char* DeleteGuildMembership();
|
||||
|
||||
/* fail::Bot inventory functions */
|
||||
static const char* QueryInventoryCount();
|
||||
static const char* LoadItems();
|
||||
static const char* SaveItems();
|
||||
static const char* DeleteItems();
|
||||
static const char* LoadItemBySlot();
|
||||
static const char* SaveItemBySlot();
|
||||
static const char* DeleteItemBySlot();
|
||||
static const char* LoadEquipmentColor();
|
||||
static const char* SaveEquipmentColor();
|
||||
|
||||
/* fail::Bot pet functions */
|
||||
static const char* LoadPetIndex();
|
||||
static const char* LoadPetSpellID();
|
||||
static const char* LoadPetStats();
|
||||
static const char* SavePetStats();
|
||||
static const char* DeletePetStats();
|
||||
static const char* LoadPetBuffs();
|
||||
static const char* SavePetBuffs();
|
||||
static const char* DeletePetBuffs();
|
||||
static const char* LoadPetItems();
|
||||
static const char* SavePetItems();
|
||||
static const char* DeletePetItems();
|
||||
|
||||
/* fail::Bot command functions */
|
||||
static const char* LoadInspectMessage();
|
||||
static const char* SaveInspectMessage();
|
||||
static const char* DeleteInspectMessage();
|
||||
static const char* SaveAllInspectMessages();
|
||||
static const char* DeleteAllInspectMessages();
|
||||
static const char* SaveAllArmorColorBySlot();
|
||||
static const char* SaveAllArmorColors();
|
||||
static const char* SaveHelmAppearance();
|
||||
static const char* SaveAllHelmAppearances();
|
||||
static const char* ToggleHelmAppearance();
|
||||
static const char* ToggleAllHelmAppearances();
|
||||
static const char* SaveFollowDistance();
|
||||
static const char* SaveAllFollowDistances();
|
||||
static const char* CreateCloneBot();
|
||||
static const char* CreateCloneBotInventory();
|
||||
|
||||
/* fail::Bot bot-group functions */
|
||||
static const char* QueryBotGroupExistence();
|
||||
static const char* LoadBotGroupIDByBotGroupName();
|
||||
static const char* LoadBotGroupIDByLeaderID();
|
||||
static const char* LoadBotGroupIDByMemberID();
|
||||
static const char* LoadLeaderIDByBotGroupName();
|
||||
static const char* LoadLeaderIDByBotGroupID();
|
||||
static const char* LoadBotGroupNameByBotGroupID();
|
||||
static const char* LoadBotGroupNameByLeaderID();
|
||||
static const char* CreateBotGroup();
|
||||
static const char* DeleteBotGroup();
|
||||
static const char* AddMemberToBotGroup();
|
||||
static const char* RemoveMemberFromBotGroup();
|
||||
static const char* LoadBotGroupIDForLoadBotGroup();
|
||||
static const char* LoadBotGroup();
|
||||
static const char* LoadBotGroupsListByOwnerID();
|
||||
|
||||
/* fail::Bot group functions */
|
||||
static const char* LoadGroupedBotsByGroupID();
|
||||
|
||||
/* fail::Bot heal rotation functions */
|
||||
static const char* LoadHealRotationIDByBotID();
|
||||
static const char* LoadHealRotation();
|
||||
static const char* LoadHealRotationMembers();
|
||||
static const char* LoadHealRotationTargets();
|
||||
static const char* SaveHealRotation();
|
||||
static const char* DeleteHealRotation();
|
||||
static const char* DeleteAllHealRotations();
|
||||
|
||||
/* fail::Bot miscellaneous functions */
|
||||
};
|
||||
|
||||
private:
|
||||
std::string query;
|
||||
};
|
||||
|
||||
extern BotDatabase botdb;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOTS
|
||||
+24
-5
@@ -1,3 +1,21 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 BOT_STRUCTS
|
||||
#define BOT_STRUCTS
|
||||
|
||||
@@ -8,11 +26,12 @@
|
||||
#include <sstream>
|
||||
|
||||
struct BotsAvailableList {
|
||||
uint32 BotID;
|
||||
char BotName[64];
|
||||
uint16 BotClass;
|
||||
uint8 BotLevel;
|
||||
uint16 BotRace;
|
||||
uint32 ID;
|
||||
char Name[64];
|
||||
uint16 Class;
|
||||
uint8 Level;
|
||||
uint16 Race;
|
||||
uint8 Gender;
|
||||
};
|
||||
|
||||
struct BotGroup {
|
||||
|
||||
+44
-10
@@ -1,8 +1,34 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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
|
||||
*/
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
#include "bot.h"
|
||||
#include "../common/string_util.h"
|
||||
|
||||
#if EQDEBUG >= 12
|
||||
#define BotAI_DEBUG_Spells 25
|
||||
#elif EQDEBUG >= 9
|
||||
#define BotAI_DEBUG_Spells 10
|
||||
#else
|
||||
#define BotAI_DEBUG_Spells -1
|
||||
#endif
|
||||
|
||||
bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
||||
|
||||
if (!tar) {
|
||||
@@ -75,7 +101,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
||||
|
||||
MakeAnyLenString(&gmsg, "Attempting to mez %s.", addMob->GetCleanName());
|
||||
|
||||
if(gmsg && GetGroupMessagesOn())
|
||||
if(gmsg)
|
||||
BotGroupSay(this, gmsg);
|
||||
}
|
||||
}
|
||||
@@ -262,7 +288,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
||||
}
|
||||
}
|
||||
|
||||
if(gmsg && GetGroupMessagesOn())
|
||||
if(gmsg)
|
||||
BotGroupSay(this, gmsg);
|
||||
}
|
||||
}
|
||||
@@ -793,7 +819,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes) {
|
||||
|
||||
MakeAnyLenString(&gmsg, "Attempting to slow %s.", tar->GetCleanName());
|
||||
|
||||
if(gmsg && GetGroupMessagesOn())
|
||||
if(gmsg)
|
||||
BotGroupSay(this, gmsg);
|
||||
}
|
||||
}
|
||||
@@ -883,7 +909,7 @@ bool Bot::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
|
||||
int32 hasMana = GetMana();
|
||||
|
||||
// Allow bots to cast buff spells even if they are out of mana
|
||||
if(RuleB(Bots, BotFinishBuffing)) {
|
||||
if(RuleB(Bots, FinishBuffing)) {
|
||||
if(manaCost > hasMana) {
|
||||
// Let's have the bots complete the buff time process
|
||||
if(AIspells[i].type & SpellType_Buff) {
|
||||
@@ -977,8 +1003,8 @@ bool Bot::AI_IdleCastCheck() {
|
||||
bool result = false;
|
||||
|
||||
if (AIautocastspell_timer->Check(false)) {
|
||||
#if MobAI_DEBUG_Spells >= 25
|
||||
std::cout << "Non-Engaged autocast check triggered: " << this->GetCleanName() << std::endl; // cout undefine [CODEBUG]
|
||||
#if BotAI_DEBUG_Spells >= 25
|
||||
Log.Out(Logs::Detail, Logs::AI, "Bot Non-Engaged autocast check triggered: %s", this->GetCleanName());
|
||||
#endif
|
||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||
|
||||
@@ -1025,7 +1051,7 @@ bool Bot::AI_IdleCastCheck() {
|
||||
// bard bots
|
||||
if(!AICastSpell(this, 100, SpellType_Cure)) {
|
||||
if(!AICastSpell(this, 100, SpellType_Heal)) {
|
||||
if((!RuleB(Bots, BotBardUseOutOfCombatSongs) || !GetBardUseOutOfCombatSongs()) || !AICastSpell(this, 100, SpellType_Buff)) { // skips if rule is false
|
||||
if((!RuleB(Bots, BotBardUseOutOfCombatSongs) || !GetAltOutOfCombatBehavior()) || !AICastSpell(this, 100, SpellType_Buff)) { // skips if rule is false
|
||||
if(!AICastSpell(this, 100, SpellType_InCombatBuff)) { // this tries to keep some combat buffs on the group until engaged code can pick up the buffing
|
||||
//
|
||||
}
|
||||
@@ -1261,7 +1287,7 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!AI_HasSpells())
|
||||
if (!AI_HasSpells())
|
||||
return false;
|
||||
|
||||
if(tar->GetAppearance() == eaDead) {
|
||||
@@ -1302,12 +1328,20 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) {
|
||||
}
|
||||
}
|
||||
|
||||
#if BotAI_DEBUG_Spells >= 10
|
||||
Log.Out(Logs::Detail, Logs::AI, "Bot::AIHealRotation: heal spellid = %u, fastheals = %c, casterlevel = %u",
|
||||
botSpell.SpellId, ((useFastHeals) ? ('T') : ('F')), GetLevel());
|
||||
#endif
|
||||
#if BotAI_DEBUG_Spells >= 25
|
||||
Log.Out(Logs::Detail, Logs::AI, "Bot::AIHealRotation: target = %s, current_time = %u, donthealmebefore = %u", tar->GetCleanName(), Timer::GetCurrentTime(), tar->DontHealMeBefore());
|
||||
#endif
|
||||
|
||||
// If there is still no spell id, then there isn't going to be one so we are done
|
||||
if(botSpell.SpellId == 0)
|
||||
if (botSpell.SpellId == 0)
|
||||
return false;
|
||||
|
||||
// Can we cast this spell on this target?
|
||||
if(!(spells[botSpell.SpellId].targettype==ST_GroupTeleport || spells[botSpell.SpellId].targettype == ST_Target || tar == this)
|
||||
if (!(spells[botSpell.SpellId].targettype == ST_GroupTeleport || spells[botSpell.SpellId].targettype == ST_Target || tar == this)
|
||||
&& !(tar->CanBuffStack(botSpell.SpellId, botLevel, true) >= 0))
|
||||
return false;
|
||||
|
||||
|
||||
+836
-845
File diff suppressed because it is too large
Load Diff
+135
-148
@@ -27,13 +27,18 @@ class Object;
|
||||
class Raid;
|
||||
class Seperator;
|
||||
class ServerPacket;
|
||||
struct Item_Struct;
|
||||
enum WaterRegionType : int;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemBase;
|
||||
}
|
||||
|
||||
#include "../common/timer.h"
|
||||
#include "../common/ptimer.h"
|
||||
#include "../common/emu_opcodes.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/eq_constants.h"
|
||||
#include "../common/emu_constants.h"
|
||||
#include "../common/eq_stream_intf.h"
|
||||
#include "../common/eq_packet.h"
|
||||
#include "../common/linked_list.h"
|
||||
@@ -42,10 +47,8 @@ struct Item_Struct;
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/guilds.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/clientversions.h"
|
||||
#include "../common/item_base.h"
|
||||
|
||||
#include "aa.h"
|
||||
#include "common.h"
|
||||
#include "merc.h"
|
||||
#include "mob.h"
|
||||
@@ -103,6 +106,7 @@ enum { //Type arguments to the Message* routines.
|
||||
|
||||
#define SPELLBAR_UNLOCK 0x2bc
|
||||
enum { //scribing argument to MemorizeSpell
|
||||
memSpellUnknown = -1, // this modifies some state data
|
||||
memSpellScribing = 0,
|
||||
memSpellMemorize = 1,
|
||||
memSpellForget = 2,
|
||||
@@ -176,6 +180,7 @@ typedef enum
|
||||
struct XTarget_Struct
|
||||
{
|
||||
XTargetType Type;
|
||||
bool dirty;
|
||||
uint16 ID;
|
||||
char Name[65];
|
||||
};
|
||||
@@ -215,10 +220,10 @@ public:
|
||||
~Client();
|
||||
|
||||
//abstract virtual function implementations required by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||
virtual Raid* GetRaid() { return entity_list.GetRaidByClient(this); }
|
||||
@@ -226,7 +231,8 @@ public:
|
||||
virtual inline bool IsBerserk() { return berserk; }
|
||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
virtual void SetAttackTimer();
|
||||
float GetQuiverHaste();
|
||||
int GetQuiverHaste(int delay);
|
||||
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||
|
||||
void AI_Init();
|
||||
void AI_Start(uint32 iMoveDelay = 0);
|
||||
@@ -249,7 +255,7 @@ public:
|
||||
void SendBuyerPacket(Client* Buyer);
|
||||
GetItems_Struct* GetTraderItems();
|
||||
void SendBazaarWelcome();
|
||||
void DyeArmor(DyeStruct* dye);
|
||||
void DyeArmor(EQEmu::TintProfile* dye);
|
||||
uint8 SlotConvert(uint8 slot,bool bracer=false);
|
||||
void Message_StringID(uint32 type, uint32 string_id, uint32 distance = 0);
|
||||
void Message_StringID(uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0);
|
||||
@@ -288,7 +294,7 @@ public:
|
||||
|
||||
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
virtual bool Process();
|
||||
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const Item_Struct* item, bool buying);
|
||||
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemBase* item, bool buying);
|
||||
void SendPacketQueue(bool Block = true);
|
||||
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
|
||||
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
|
||||
@@ -300,7 +306,7 @@ public:
|
||||
void VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber);
|
||||
void SendSound();
|
||||
void LearnRecipe(uint32 recipeID);
|
||||
bool CanIncreaseTradeskill(SkillUseTypes tradeskill);
|
||||
bool CanIncreaseTradeskill(EQEmu::skills::SkillType tradeskill);
|
||||
|
||||
EQApplicationPacket* ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type);
|
||||
|
||||
@@ -322,6 +328,7 @@ public:
|
||||
/* New PP Save Functions */
|
||||
bool SaveCurrency(){ return database.SaveCharacterCurrency(this->CharacterID(), &m_pp); }
|
||||
bool SaveAA();
|
||||
void RemoveExpendedAA(int aa_id);
|
||||
|
||||
inline bool ClientDataLoaded() const { return client_data_loaded; }
|
||||
inline bool Connected() const { return (client_state == CLIENT_CONNECTED); }
|
||||
@@ -355,9 +362,9 @@ public:
|
||||
int32 LevelRegen();
|
||||
void HPTick();
|
||||
void SetGM(bool toggle);
|
||||
void SetPVP(bool toggle);
|
||||
void SetPVP(bool toggle, bool message = true);
|
||||
|
||||
inline bool GetPVP() const { return zone->GetZoneID() == 77 ? true : (m_pp.pvp != 0); }
|
||||
inline bool GetPVP() const { return m_pp.pvp != 0; }
|
||||
inline bool GetGM() const { return m_pp.gm != 0; }
|
||||
|
||||
inline void SetBaseClass(uint32 i) { m_pp.class_=i; }
|
||||
@@ -396,7 +403,7 @@ public:
|
||||
|
||||
inline uint8 GetLanguageSkill(uint16 n) const { return m_pp.languages[n]; }
|
||||
|
||||
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const Item_Struct* item = nullptr);
|
||||
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQEmu::ItemBase* item = nullptr);
|
||||
|
||||
inline const char* GetLastName() const { return lastname; }
|
||||
|
||||
@@ -412,7 +419,7 @@ public:
|
||||
virtual void CalcBonuses();
|
||||
//these are all precalculated now
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(SkillOffense)) * 9 / 10); }
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQEmu::skills::SkillOffense)) * 9 / 10); }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
inline virtual int GetHaste() const { return Haste; }
|
||||
int GetRawACNoShield(int &shield_ac) const;
|
||||
@@ -506,6 +513,8 @@ public:
|
||||
virtual int GetMaxSongSlots() const { return 12; }
|
||||
virtual int GetMaxDiscSlots() const { return 1; }
|
||||
virtual int GetMaxTotalSlots() const { return 38; }
|
||||
virtual uint32 GetFirstBuffSlot(bool disc, bool song);
|
||||
virtual uint32 GetLastBuffSlot(bool disc, bool song);
|
||||
virtual void InitializeBuffSlots();
|
||||
virtual void UninitializeBuffSlots();
|
||||
|
||||
@@ -541,7 +550,6 @@ public:
|
||||
|
||||
bool Flurry();
|
||||
bool Rampage();
|
||||
void DurationRampage(uint32 duration);
|
||||
|
||||
inline uint32 GetEXP() const { return m_pp.exp; }
|
||||
|
||||
@@ -557,6 +565,7 @@ public:
|
||||
void SendCrystalCounts();
|
||||
|
||||
void AddEXP(uint32 in_add_exp, uint8 conlevel = 0xFF, bool resexp = false);
|
||||
uint32 CalcEXP(uint8 conlevel = 0xFF);
|
||||
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
|
||||
void AddLevelBasedExp(uint8 exp_percentage, uint8 max_level=0);
|
||||
void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp);
|
||||
@@ -581,8 +590,8 @@ public:
|
||||
|
||||
void GoToBind(uint8 bindnum = 0);
|
||||
void GoToSafeCoords(uint16 zone_id, uint16 instance_id);
|
||||
void Gate();
|
||||
void SetBindPoint(int to_zone = -1, int to_instance = 0, const glm::vec3& location = glm::vec3());
|
||||
void Gate(uint8 bindnum = 0);
|
||||
void SetBindPoint(int bind_num = 0, int to_zone = -1, int to_instance = 0, const glm::vec3& location = glm::vec3());
|
||||
void SetStartZone(uint32 zoneid, float x = 0.0f, float y =0.0f, float z = 0.0f);
|
||||
uint32 GetStartZone(void);
|
||||
void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited);
|
||||
@@ -592,7 +601,7 @@ public:
|
||||
void AssignToInstance(uint16 instance_id);
|
||||
void RemoveFromInstance(uint16 instance_id);
|
||||
void WhoAll();
|
||||
bool CheckLoreConflict(const Item_Struct* item);
|
||||
bool CheckLoreConflict(const EQEmu::ItemBase* item);
|
||||
void ChangeLastName(const char* in_lastname);
|
||||
void GetGroupAAs(GroupLeadershipAA_Struct *into) const;
|
||||
void GetRaidAAs(RaidLeadershipAA_Struct *into) const;
|
||||
@@ -611,7 +620,7 @@ public:
|
||||
void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max);
|
||||
|
||||
void UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest = false);
|
||||
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
||||
int32 GetRawItemAC();
|
||||
uint16 GetCombinedAC_TEST();
|
||||
@@ -622,6 +631,7 @@ public:
|
||||
inline uint32 AccountID() const { return account_id; }
|
||||
|
||||
inline const char* AccountName()const { return account_name; }
|
||||
inline int GetAccountCreation() const { return account_creation; }
|
||||
inline int16 Admin() const { return admin; }
|
||||
inline uint32 CharacterID() const { return character_id; }
|
||||
void UpdateAdmin(bool iFromDB = true);
|
||||
@@ -662,6 +672,8 @@ public:
|
||||
bool HasMoney(uint64 copper);
|
||||
uint64 GetCarriedMoney();
|
||||
uint64 GetAllMoney();
|
||||
uint32 GetMoney(uint8 type, uint8 subtype);
|
||||
int GetAccountAge();
|
||||
|
||||
bool IsDiscovered(uint32 itemid);
|
||||
void DiscoverItem(uint32 itemid);
|
||||
@@ -673,31 +685,31 @@ public:
|
||||
uint16 GetSkillPoints() { return m_pp.points;}
|
||||
void SetSkillPoints(int inp) { m_pp.points = inp;}
|
||||
|
||||
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
|
||||
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= EQEmu::skills::HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
|
||||
void IncreaseLanguageSkill(int skill_id, int value = 1);
|
||||
virtual uint16 GetSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return((itembonuses.skillmod[skill_id] > 0) ? m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100 : m_pp.skills[skill_id]); } return 0; }
|
||||
uint32 GetRawSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
|
||||
bool HasSkill(SkillUseTypes skill_id) const;
|
||||
bool CanHaveSkill(SkillUseTypes skill_id) const;
|
||||
void SetSkill(SkillUseTypes skill_num, uint16 value);
|
||||
void AddSkill(SkillUseTypes skillid, uint16 value);
|
||||
virtual uint16 GetSkill(EQEmu::skills::SkillType skill_id) const { if (skill_id <= EQEmu::skills::HIGHEST_SKILL) { return(itembonuses.skillmod[skill_id] > 0 ? (itembonuses.skillmodmax[skill_id] > 0 ? std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id]); } return 0; }
|
||||
uint32 GetRawSkill(EQEmu::skills::SkillType skill_id) const { if (skill_id <= EQEmu::skills::HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
|
||||
bool HasSkill(EQEmu::skills::SkillType skill_id) const;
|
||||
bool CanHaveSkill(EQEmu::skills::SkillType skill_id) const;
|
||||
void SetSkill(EQEmu::skills::SkillType skill_num, uint16 value);
|
||||
void AddSkill(EQEmu::skills::SkillType skillid, uint16 value);
|
||||
void CheckSpecializeIncrease(uint16 spell_id);
|
||||
void CheckSongSkillIncrease(uint16 spell_id);
|
||||
bool CheckIncreaseSkill(SkillUseTypes skillid, Mob *against_who, int chancemodi = 0);
|
||||
bool CheckIncreaseSkill(EQEmu::skills::SkillType skillid, Mob *against_who, int chancemodi = 0);
|
||||
void CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill);
|
||||
void SetLanguageSkill(int langid, int value);
|
||||
void SetHoTT(uint32 mobid);
|
||||
void ShowSkillsWindow();
|
||||
void SendStatsWindow(Client* client, bool use_window);
|
||||
|
||||
uint16 MaxSkill(SkillUseTypes skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(SkillUseTypes skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
uint8 SkillTrainLevel(SkillUseTypes skillid, uint16 class_);
|
||||
uint16 MaxSkill(EQEmu::skills::SkillType skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(EQEmu::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
uint8 SkillTrainLevel(EQEmu::skills::SkillType skillid, uint16 class_);
|
||||
|
||||
void TradeskillSearchResults(const std::string query, unsigned long objtype, unsigned long someid);
|
||||
void TradeskillSearchResults(const std::string &query, unsigned long objtype, unsigned long someid);
|
||||
void SendTradeskillDetails(uint32 recipe_id);
|
||||
bool TradeskillExecute(DBTradeskillRecipe_Struct *spec);
|
||||
void CheckIncreaseTradeskill(int16 bonusstat, int16 stat_modifier, float skillup_modifier, uint16 success_modifier, SkillUseTypes tradeskill);
|
||||
void CheckIncreaseTradeskill(int16 bonusstat, int16 stat_modifier, float skillup_modifier, uint16 success_modifier, EQEmu::skills::SkillType tradeskill);
|
||||
|
||||
void GMKill();
|
||||
inline bool IsMedding() const {return medding;}
|
||||
@@ -708,6 +720,7 @@ public:
|
||||
// use this one instead
|
||||
void MemSpell(uint16 spell_id, int slot, bool update_client = true);
|
||||
void UnmemSpell(int slot, bool update_client = true);
|
||||
void UnmemSpellBySpellID(int32 spell_id);
|
||||
void UnmemSpellAll(bool update_client = true);
|
||||
void ScribeSpell(uint16 spell_id, int slot, bool update_client = true);
|
||||
void UnscribeSpell(int slot, bool update_client = true);
|
||||
@@ -731,7 +744,7 @@ public:
|
||||
#endif
|
||||
uint32 GetEquipment(uint8 material_slot) const; // returns item id
|
||||
uint32 GetEquipmentColor(uint8 material_slot) const;
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = m_inv.FindBrightestLightType(); m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment); }
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type[EQEmu::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]); }
|
||||
|
||||
inline bool AutoSplitEnabled() { return m_pp.autosplit != 0; }
|
||||
|
||||
@@ -758,45 +771,35 @@ public:
|
||||
|
||||
inline PTimerList &GetPTimers() { return(p_timers); }
|
||||
|
||||
//AA Methods
|
||||
void SendAAList();
|
||||
void ResetAA();
|
||||
void SendClearAA();
|
||||
void SendAA(uint32 id, int seq=1);
|
||||
void SendPreviousAA(uint32 id, int seq=1);
|
||||
void BuyAA(AA_Action* action);
|
||||
//this function is used by some AA stuff
|
||||
void MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing);
|
||||
void SetAATitle(const char *Title);
|
||||
void SetTitleSuffix(const char *txt);
|
||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||
void SendAAStats();
|
||||
void SendAATable();
|
||||
void SendAATimers();
|
||||
int GetAATimerID(aaID activate);
|
||||
int CalcAAReuseTimer(const AA_DBAction *caa);
|
||||
void ActivateAA(aaID activate);
|
||||
void SendAATimer(uint32 ability, uint32 begin, uint32 end);
|
||||
void EnableAAEffect(aaEffectType type, uint32 duration = 0);
|
||||
void DisableAAEffect(aaEffectType type);
|
||||
bool CheckAAEffect(aaEffectType type);
|
||||
void HandleAAAction(aaID activate);
|
||||
uint32 GetAA(uint32 aa_id) const;
|
||||
bool SetAA(uint32 aa_id, uint32 new_value);
|
||||
inline uint32 GetAAPointsSpent() { return m_pp.aapoints_spent; }
|
||||
int16 CalcAAFocusEffect(focusType type, uint16 focus_spell, uint16 spell_id);
|
||||
int16 CalcAAFocus(focusType type, uint32 aa_ID, uint16 spell_id);
|
||||
void SetAAPoints(uint32 points) { m_pp.aapoints = points; SendAAStats(); }
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAAStats(); }
|
||||
//New AA Methods
|
||||
void SendAlternateAdvancementRank(int aa_id, int level);
|
||||
void SendAlternateAdvancementTable();
|
||||
void SendAlternateAdvancementStats();
|
||||
void PurchaseAlternateAdvancementRank(int rank_id);
|
||||
bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost = false);
|
||||
void IncrementAlternateAdvancementRank(int rank_id);
|
||||
void ActivateAlternateAdvancementAbility(int rank_id, int target_id);
|
||||
void SendAlternateAdvancementPoints();
|
||||
void SendAlternateAdvancementTimer(int ability, int begin, int end);
|
||||
void SendAlternateAdvancementTimers();
|
||||
void ResetAlternateAdvancementTimer(int ability);
|
||||
void ResetAlternateAdvancementTimers();
|
||||
|
||||
void SetAAPoints(uint32 points) { m_pp.aapoints = points; SendAlternateAdvancementStats(); }
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAlternateAdvancementStats(); }
|
||||
int GetAAPoints() { return m_pp.aapoints; }
|
||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||
|
||||
//old AA methods that we still use
|
||||
void ResetAA();
|
||||
void RefundAA();
|
||||
void IncrementAA(int aa_id);
|
||||
int32 GetAAEffectDataBySlot(uint32 aa_ID, uint32 slot_id, bool GetEffect, bool GetBase1, bool GetBase2);
|
||||
int32 GetAAEffectid(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, true, false,false); }
|
||||
int32 GetAABase1(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, false, true,false); }
|
||||
int32 GetAABase2(uint32 aa_ID, uint32 slot_id) { return GetAAEffectDataBySlot(aa_ID, slot_id, false, false,true); }
|
||||
void SendClearAA();
|
||||
inline uint32 GetMaxAAXP(void) const { return max_AAXP; }
|
||||
inline uint32 GetAAXP() const { return m_pp.expAA; }
|
||||
int16 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id);
|
||||
void SetAATitle(const char *Title);
|
||||
void SetTitleSuffix(const char *txt);
|
||||
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing);
|
||||
int32 acmod();
|
||||
|
||||
// Item methods
|
||||
@@ -804,7 +807,7 @@ public:
|
||||
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
|
||||
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
|
||||
void SetTint(int16 slot_id, uint32 color);
|
||||
void SetTint(int16 slot_id, Color_Struct& color);
|
||||
void SetTint(int16 slot_id, EQEmu::Tint_Struct& color);
|
||||
void SetMaterial(int16 slot_id, uint32 item_id);
|
||||
void Undye();
|
||||
int32 GetItemIDAt(int16 slot_id);
|
||||
@@ -818,59 +821,12 @@ public:
|
||||
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
|
||||
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
|
||||
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
|
||||
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
|
||||
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = EQEmu::legacy::SlotCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
|
||||
void SetStats(uint8 type,int16 set_val);
|
||||
void IncStats(uint8 type,int16 increase_val);
|
||||
void DropItem(int16 slot_id);
|
||||
|
||||
//
|
||||
// class Client::TextLink
|
||||
//
|
||||
class TextLink {
|
||||
public:
|
||||
enum LinkType { linkBlank = 0, linkItemData, linkLootItem, linkItemInst };
|
||||
|
||||
TextLink() { Reset(); }
|
||||
|
||||
void SetLinkType(LinkType linkType) { m_LinkType = linkType; }
|
||||
void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; }
|
||||
void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; }
|
||||
void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; }
|
||||
void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to
|
||||
void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use
|
||||
void SetTaskUse() { m_TaskUse = true; }
|
||||
|
||||
std::string GenerateLink();
|
||||
bool LinkError() { return m_Error; }
|
||||
|
||||
std::string GetLink() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
|
||||
std::string GetLinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
||||
std::string GetLinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
||||
|
||||
void Reset();
|
||||
|
||||
static bool DegenerateLinkBody(TextLinkBody_Struct& textLinkBodyStruct, const std::string& textLinkBody);
|
||||
static bool GenerateLinkBody(std::string& textLinkBody, const TextLinkBody_Struct& textLinkBodyStruct);
|
||||
|
||||
private:
|
||||
void generate_body();
|
||||
void generate_text();
|
||||
|
||||
int m_LinkType;
|
||||
const Item_Struct* m_ItemData;
|
||||
const ServerLootItem_Struct* m_LootData;
|
||||
const ItemInst* m_ItemInst;
|
||||
uint32 m_ProxyItemID;
|
||||
const char* m_ProxyText;
|
||||
bool m_TaskUse;
|
||||
TextLinkBody_Struct m_LinkBodyStruct;
|
||||
std::string m_Link;
|
||||
std::string m_LinkBody;
|
||||
std::string m_LinkText;
|
||||
bool m_Error;
|
||||
};
|
||||
|
||||
int GetItemLinkHash(const ItemInst* inst); // move to Item_Struct..or make use of the pre-calculated database field
|
||||
int GetItemLinkHash(const ItemInst* inst); // move to ItemBase..or make use of the pre-calculated database field
|
||||
|
||||
void SendItemLink(const ItemInst* inst, bool sendtoall=false);
|
||||
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
|
||||
@@ -883,7 +839,10 @@ public:
|
||||
eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; }
|
||||
void SetFilter(eqFilterType filter_id, eqFilterMode value) { ClientFilters[filter_id]=value; }
|
||||
|
||||
void CancelSneakHide();
|
||||
void BreakInvis();
|
||||
void BreakSneakWhenCastOn(Mob* caster, bool IsResisted);
|
||||
void BreakFeignDeathWhenCastOn(bool IsResisted);
|
||||
void LeaveGroup();
|
||||
|
||||
bool Hungry() const {if (GetGM()) return false; return m_pp.hunger_level <= 3000;}
|
||||
@@ -897,14 +856,17 @@ public:
|
||||
bool CheckTradeLoreConflict(Client* other);
|
||||
void LinkDead();
|
||||
void Insight(uint32 t_id);
|
||||
bool CheckDoubleAttack(bool tripleAttack = false);
|
||||
bool CheckDoubleAttack();
|
||||
bool CheckTripleAttack();
|
||||
bool CheckDoubleRangedAttack();
|
||||
bool CheckDualWield();
|
||||
|
||||
//remove charges/multiple objects from inventory:
|
||||
//bool DecreaseByType(uint32 type, uint8 amt);
|
||||
bool DecreaseByID(uint32 type, uint8 amt);
|
||||
uint8 SlotConvert2(uint8 slot); //Maybe not needed.
|
||||
void Escape(); //AA Escape
|
||||
void DisenchantSummonedBags(bool client_update = true);
|
||||
void RemoveNoRent(bool client_update = true);
|
||||
void RemoveDuplicateLore(bool client_update = true);
|
||||
void MoveSlotNotAllowed(bool client_update = true);
|
||||
@@ -926,10 +888,15 @@ public:
|
||||
void ResetTrade();
|
||||
void DropInst(const ItemInst* inst);
|
||||
bool TrainDiscipline(uint32 itemid);
|
||||
void TrainDiscBySpellID(int32 spell_id);
|
||||
int GetDiscSlotBySpellID(int32 spellid);
|
||||
void SendDisciplineUpdate();
|
||||
void SendDisciplineTimer(uint32 timer_id, uint32 duration);
|
||||
bool UseDiscipline(uint32 spell_id, uint32 target);
|
||||
|
||||
void SetLinkedSpellReuseTimer(uint32 timer_id, uint32 duration);
|
||||
bool IsLinkedSpellReuseTimerReady(uint32 timer_id);
|
||||
|
||||
bool CheckTitle(int titleset);
|
||||
void EnableTitle(int titleset);
|
||||
void RemoveTitle(int titleset);
|
||||
@@ -959,7 +926,7 @@ public:
|
||||
|
||||
//This is used to later set the buff duration of the spell, in slot to duration.
|
||||
//Doesn't appear to work directly after the client recieves an action packet.
|
||||
void SendBuffDurationPacket(Buffs_Struct &buff);
|
||||
void SendBuffDurationPacket(Buffs_Struct &buff, int slot);
|
||||
void SendBuffNumHitPacket(Buffs_Struct &buff, int slot);
|
||||
|
||||
void ProcessInspectRequest(Client* requestee, Client* requester);
|
||||
@@ -968,7 +935,7 @@ public:
|
||||
int GetNextAvailableSpellBookSlot(int starting_slot = 0);
|
||||
inline uint32 GetSpellByBookSlot(int book_slot) { return m_pp.spell_book[book_slot]; }
|
||||
inline bool HasSpellScribed(int spellid) { return (FindSpellBookSlotBySpellID(spellid) != -1 ? true : false); }
|
||||
uint16 GetMaxSkillAfterSpecializationRules(SkillUseTypes skillid, uint16 maxSkill);
|
||||
uint16 GetMaxSkillAfterSpecializationRules(EQEmu::skills::SkillType skillid, uint16 maxSkill);
|
||||
void SendPopupToClient(const char *Title, const char *Text, uint32 PopupID = 0, uint32 Buttons = 0, uint32 Duration = 0);
|
||||
void SendWindow(uint32 PopupID, uint32 NegativeID, uint32 Buttons, const char *ButtonName0, const char *ButtonName1, uint32 Duration, int title_type, Client* target, const char *Title, const char *Text, ...);
|
||||
bool PendingTranslocate;
|
||||
@@ -997,13 +964,13 @@ public:
|
||||
inline void UpdateTasksForItem(ActivityType Type, int ItemID, int Count=1) { if(taskstate) taskstate->UpdateTasksForItem(this, Type, ItemID, Count); }
|
||||
inline void UpdateTasksOnExplore(int ExploreID) { if(taskstate) taskstate->UpdateTasksOnExplore(this, ExploreID); }
|
||||
inline bool UpdateTasksOnSpeakWith(int NPCTypeID) { if(taskstate) return taskstate->UpdateTasksOnSpeakWith(this, NPCTypeID); else return false; }
|
||||
inline bool UpdateTasksOnDeliver(uint32 *Items, int Cash, int NPCTypeID) { if(taskstate) return taskstate->UpdateTasksOnDeliver(this, Items, Cash, NPCTypeID); else return false; }
|
||||
inline bool UpdateTasksOnDeliver(std::list<ItemInst*>& Items, int Cash, int NPCTypeID) { if (taskstate) return taskstate->UpdateTasksOnDeliver(this, Items, Cash, NPCTypeID); else return false; }
|
||||
inline void TaskSetSelector(Mob *mob, int TaskSetID) { if(taskmanager) taskmanager->TaskSetSelector(this, taskstate, mob, TaskSetID); }
|
||||
inline void EnableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->EnableTask(CharacterID(), TaskCount, TaskList); }
|
||||
inline void DisableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->DisableTask(CharacterID(), TaskCount, TaskList); }
|
||||
inline bool IsTaskEnabled(int TaskID) { return (taskstate ? taskstate->IsTaskEnabled(TaskID) : false); }
|
||||
inline void ProcessTaskProximities(float X, float Y, float Z) { if(taskstate) taskstate->ProcessTaskProximities(this, X, Y, Z); }
|
||||
inline void AssignTask(int TaskID, int NPCID) { if(taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID); }
|
||||
inline void AssignTask(int TaskID, int NPCID, bool enforce_level_requirement = false) { if (taskstate) taskstate->AcceptNewTask(this, TaskID, NPCID, enforce_level_requirement); }
|
||||
inline int ActiveSpeakTask(int NPCID) { if(taskstate) return taskstate->ActiveSpeakTask(NPCID); else return 0; }
|
||||
inline int ActiveSpeakActivity(int NPCID, int TaskID) { if(taskstate) return taskstate->ActiveSpeakActivity(NPCID, TaskID); else return 0; }
|
||||
inline void FailTask(int TaskID) { if(taskstate) taskstate->FailTask(this, TaskID); }
|
||||
@@ -1021,9 +988,9 @@ public:
|
||||
inline int ActiveTasksInSet(int TaskSet) { return (taskstate ? taskstate->ActiveTasksInSet(TaskSet) :0); }
|
||||
inline int CompletedTasksInSet(int TaskSet) { return (taskstate ? taskstate->CompletedTasksInSet(TaskSet) :0); }
|
||||
|
||||
inline const ClientVersion GetClientVersion() const { return m_ClientVersion; }
|
||||
inline const uint32 GetClientVersionBit() const { return m_ClientVersionBit; }
|
||||
inline void SetClientVersion(ClientVersion in) { m_ClientVersion = in; }
|
||||
inline const EQEmu::versions::ClientVersion ClientVersion() const { return m_ClientVersion; }
|
||||
inline const uint32 ClientVersionBit() const { return m_ClientVersionBit; }
|
||||
inline void SetClientVersion(EQEmu::versions::ClientVersion client_version) { m_ClientVersion = client_version; }
|
||||
|
||||
/** Adventure Stuff **/
|
||||
void SendAdventureError(const char *error);
|
||||
@@ -1129,6 +1096,7 @@ public:
|
||||
inline bool IsDraggingCorpse() { return (DraggedCorpses.size() > 0); }
|
||||
void DragCorpses();
|
||||
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
||||
inline void ResetPositionTimer() { position_timer_counter = 0; }
|
||||
void SendAltCurrencies();
|
||||
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
||||
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method = 0);
|
||||
@@ -1140,20 +1108,22 @@ public:
|
||||
void HandleLFGuildResponse(ServerPacket *pack);
|
||||
void SendLFGuildStatus();
|
||||
void SendGuildLFGuildStatus();
|
||||
inline bool XTargettingAvailable() const { return ((m_ClientVersionBit & BIT_UFAndLater) && RuleB(Character, EnableXTargetting)); }
|
||||
inline bool XTargettingAvailable() const { return ((m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) && RuleB(Character, EnableXTargetting)); }
|
||||
inline uint8 GetMaxXTargets() const { return MaxXTargets; }
|
||||
void SetMaxXTargets(uint8 NewMax);
|
||||
bool IsXTarget(const Mob *m) const;
|
||||
bool IsClientXTarget(const Client *c) const;
|
||||
void UpdateClientXTarget(Client *c);
|
||||
void UpdateXTargetType(XTargetType Type, Mob *m, const char *Name = nullptr);
|
||||
void AddAutoXTarget(Mob *m);
|
||||
void AddAutoXTarget(Mob *m, bool send = true);
|
||||
void RemoveXTarget(Mob *m, bool OnlyAutoSlots);
|
||||
void SendXTargetPacket(uint32 Slot, Mob *m);
|
||||
void SendXTargetUpdates();
|
||||
void RemoveGroupXTargets();
|
||||
void RemoveAutoXTargets();
|
||||
void ShowXTargets(Client *c);
|
||||
bool GroupFollow(Client* inviter);
|
||||
inline bool GetRunMode() const { return runmode; }
|
||||
|
||||
void InitializeMercInfo();
|
||||
bool CheckCanSpawnMerc(uint32 template_id);
|
||||
@@ -1213,13 +1183,14 @@ public:
|
||||
int32 GetActCHA() { return( std::min(GetMaxCHA(), GetCHA()) ); }
|
||||
void LoadAccountFlags();
|
||||
void SetAccountFlag(std::string flag, std::string val);
|
||||
std::string GetAccountFlag(std::string flag); float GetDamageMultiplier(SkillUseTypes);
|
||||
void Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_consume);
|
||||
std::string GetAccountFlag(std::string flag);
|
||||
float GetDamageMultiplier(EQEmu::skills::SkillType how_long_has_this_been_missing);
|
||||
void Consume(const EQEmu::ItemBase *item, uint8 type, int16 slot, bool auto_consume);
|
||||
void PlayMP3(const char* fname);
|
||||
void ExpeditionSay(const char *str, int ExpID);
|
||||
int mod_client_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemInst* weapon, Mob* other);
|
||||
int mod_client_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const ItemInst* weapon, Mob* other);
|
||||
bool mod_client_message(char* message, uint8 chan_num);
|
||||
bool mod_can_increase_skill(SkillUseTypes skillid, Mob* against_who);
|
||||
bool mod_can_increase_skill(EQEmu::skills::SkillType skillid, Mob* against_who);
|
||||
int16 mod_increase_skill_chance(int16 chance, Mob* against_who);
|
||||
int mod_bindwound_percent(int max_percent, Mob* bindmob);
|
||||
int mod_bindwound_hp(int bindhps, Mob* bindmob);
|
||||
@@ -1236,9 +1207,9 @@ public:
|
||||
int32 mod_client_xp(int32 in_exp, NPC *npc);
|
||||
uint32 mod_client_xp_for_level(uint32 xp, uint16 check_level);
|
||||
int mod_client_haste_cap(int cap);
|
||||
int mod_consume(Item_Struct *item, ItemUseTypes type, int change);
|
||||
int mod_food_value(const Item_Struct *item, int change);
|
||||
int mod_drink_value(const Item_Struct *item, int change);
|
||||
int mod_consume(EQEmu::ItemBase *item, EQEmu::item::ItemType type, int change);
|
||||
int mod_food_value(const EQEmu::ItemBase *item, int change);
|
||||
int mod_drink_value(const EQEmu::ItemBase *item, int change);
|
||||
|
||||
void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; }
|
||||
bool GetEngagedRaidTarget() const { return EngagedRaidTarget; }
|
||||
@@ -1250,25 +1221,40 @@ public:
|
||||
|
||||
bool InterrogateInventory(Client* requester, bool log, bool silent, bool allowtrip, bool& error, bool autolog = true);
|
||||
|
||||
void SetNextInvSnapshot(uint32 interval_in_min) {
|
||||
m_epp.last_invsnapshot_time = time(nullptr);
|
||||
m_epp.next_invsnapshot_time = m_epp.last_invsnapshot_time + (interval_in_min * 60);
|
||||
}
|
||||
uint32 GetLastInvSnapshotTime() { return m_epp.last_invsnapshot_time; }
|
||||
uint32 GetNextInvSnapshotTime() { return m_epp.next_invsnapshot_time; }
|
||||
|
||||
//Command #Tune functions
|
||||
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
|
||||
|
||||
void QuestReward(Mob* target, uint32 copper = 0, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0, uint32 itemid = 0, uint32 exp = 0, bool faction = false);
|
||||
|
||||
void ResetHPUpdateTimer() { hpupdate_timer.Start(); }
|
||||
|
||||
void SendHPUpdateMarquee();
|
||||
|
||||
void CheckRegionTypeChanges();
|
||||
|
||||
protected:
|
||||
friend class Mob;
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false);
|
||||
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false);
|
||||
void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false);
|
||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||
void CalcEdibleBonuses(StatBonuses* newbon);
|
||||
void CalcAABonuses(StatBonuses* newbon);
|
||||
void ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon);
|
||||
void ProcessItemCaps();
|
||||
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
||||
bool client_data_loaded;
|
||||
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
int16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
||||
uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
||||
|
||||
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost);
|
||||
|
||||
Mob* bind_sight_target;
|
||||
|
||||
@@ -1379,6 +1365,7 @@ private:
|
||||
bool AFK;
|
||||
bool auto_attack;
|
||||
bool auto_fire;
|
||||
bool runmode;
|
||||
uint8 gmspeed;
|
||||
bool medding;
|
||||
uint16 horseId;
|
||||
@@ -1437,10 +1424,14 @@ private:
|
||||
uint8 zonesummon_ignorerestrictions;
|
||||
ZoneMode zone_mode;
|
||||
|
||||
WaterRegionType last_region_type;
|
||||
|
||||
Timer position_timer;
|
||||
uint8 position_timer_counter;
|
||||
|
||||
// this is used to try to cut back on position update reflections
|
||||
int position_update_same_count;
|
||||
|
||||
PTimerList p_timers; //persistent timers
|
||||
Timer hpupdate_timer;
|
||||
Timer camp_timer;
|
||||
@@ -1483,11 +1474,7 @@ private:
|
||||
|
||||
uint32 tribute_master_id;
|
||||
|
||||
FILE *SQL_log;
|
||||
uint32 max_AAXP;
|
||||
uint32 staminacount;
|
||||
AA_Array* aa[MAX_PP_AA_ARRAY]; //this list contains pointers into our player profile
|
||||
std::map<uint32,uint8> aa_points;
|
||||
bool npcflag;
|
||||
uint8 npclevel;
|
||||
bool feigned;
|
||||
@@ -1518,7 +1505,7 @@ private:
|
||||
Timer *GlobalChatLimiterTimer; //60 seconds
|
||||
uint32 AttemptedMessages;
|
||||
|
||||
ClientVersion m_ClientVersion;
|
||||
EQEmu::versions::ClientVersion m_ClientVersion;
|
||||
uint32 m_ClientVersionBit;
|
||||
|
||||
int XPRate;
|
||||
|
||||
+193
-132
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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
|
||||
@@ -42,7 +42,7 @@ int32 Client::GetMaxStat() const
|
||||
if (level < 61) {
|
||||
base = 255;
|
||||
}
|
||||
else if (GetClientVersion() >= ClientVersion::SoF) {
|
||||
else if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
base = 255 + 5 * (level - 60);
|
||||
}
|
||||
else if (level < 71) {
|
||||
@@ -58,8 +58,8 @@ int32 Client::GetMaxResist() const
|
||||
{
|
||||
int level = GetLevel();
|
||||
int32 base = 500;
|
||||
if (level > 60) {
|
||||
base += ((level - 60) * 5);
|
||||
if (level > 65) {
|
||||
base += ((level - 65) * 5);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ int32 Client::LevelRegen()
|
||||
bool sitting = IsSitting();
|
||||
bool feigned = GetFeigned();
|
||||
int level = GetLevel();
|
||||
bool bonus = GetRaceBitmask(GetBaseRace()) & RuleI(Character, BaseHPRegenBonusRaces);
|
||||
bool bonus = GetPlayerRaceBit(GetBaseRace()) & RuleI(Character, BaseHPRegenBonusRaces);
|
||||
uint8 multiplier1 = bonus ? 2 : 1;
|
||||
int32 hp = 0;
|
||||
//these calculations should match up with the info from Monkly Business, which was last updated ~05/2008: http://www.monkly-business.net/index.php?pageid=abilities
|
||||
@@ -409,7 +409,7 @@ uint32 Mob::GetClassLevelFactor()
|
||||
|
||||
int32 Client::CalcBaseHP()
|
||||
{
|
||||
if (GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
int stats = GetSTA();
|
||||
if (stats > 255) {
|
||||
stats = (stats - 255) / 2;
|
||||
@@ -485,9 +485,9 @@ int32 Client::GetRawItemAC()
|
||||
{
|
||||
int32 Total = 0;
|
||||
// this skips MainAmmo..add an '=' conditional if that slot is required (original behavior)
|
||||
for (int16 slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id < EmuConstants::EQUIPMENT_END; slot_id++) {
|
||||
for (int16 slot_id = EQEmu::legacy::EQUIPMENT_BEGIN; slot_id < EQEmu::legacy::EQUIPMENT_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst && inst->IsType(ItemClassCommon)) {
|
||||
if (inst && inst->IsClassCommon()) {
|
||||
Total += inst->GetItem()->AC;
|
||||
}
|
||||
}
|
||||
@@ -1032,21 +1032,28 @@ int32 Client::acmod()
|
||||
int32 Client::CalcAC()
|
||||
{
|
||||
// new formula
|
||||
int avoidance = (acmod() + ((GetSkill(SkillDefense) + itembonuses.HeroicAGI / 10) * 16) / 9);
|
||||
int avoidance = (acmod() + ((GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) * 16) / 9);
|
||||
if (avoidance < 0) {
|
||||
avoidance = 0;
|
||||
}
|
||||
|
||||
if (RuleB(Character, EnableAvoidanceCap)) {
|
||||
if (avoidance > RuleI(Character, AvoidanceCap)) {
|
||||
avoidance = RuleI(Character, AvoidanceCap);
|
||||
}
|
||||
}
|
||||
|
||||
int mitigation = 0;
|
||||
if (m_pp.class_ == WIZARD || m_pp.class_ == MAGICIAN || m_pp.class_ == NECROMANCER || m_pp.class_ == ENCHANTER) {
|
||||
//something is wrong with this, naked casters have the wrong natural AC
|
||||
// mitigation = (spellbonuses.AC/3) + (GetSkill(DEFENSE)/2) + (itembonuses.AC+1);
|
||||
mitigation = (GetSkill(SkillDefense) + itembonuses.HeroicAGI / 10) / 4 + (itembonuses.AC + 1);
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 4 + (itembonuses.AC + 1);
|
||||
//this might be off by 4..
|
||||
mitigation -= 4;
|
||||
}
|
||||
else {
|
||||
// mitigation = (spellbonuses.AC/4) + (GetSkill(DEFENSE)/3) + ((itembonuses.AC*4)/3);
|
||||
mitigation = (GetSkill(SkillDefense) + itembonuses.HeroicAGI / 10) / 3 + ((itembonuses.AC * 4) / 3);
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 3 + ((itembonuses.AC * 4) / 3);
|
||||
if (m_pp.class_ == MONK) {
|
||||
mitigation += GetLevel() * 13 / 10; //the 13/10 might be wrong, but it is close...
|
||||
}
|
||||
@@ -1067,10 +1074,10 @@ int32 Client::CalcAC()
|
||||
}
|
||||
// Shield AC bonus for HeroicSTR
|
||||
if (itembonuses.HeroicSTR) {
|
||||
bool equiped = CastToClient()->m_inv.GetItem(MainSecondary);
|
||||
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary);
|
||||
if (equiped) {
|
||||
uint8 shield = CastToClient()->m_inv.GetItem(MainSecondary)->GetItem()->ItemType;
|
||||
if (shield == ItemTypeShield) {
|
||||
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary)->GetItem()->ItemType;
|
||||
if (shield == EQEmu::item::ItemTypeShield) {
|
||||
displayed += itembonuses.HeroicSTR / 2;
|
||||
}
|
||||
}
|
||||
@@ -1085,21 +1092,21 @@ int32 Client::GetACMit()
|
||||
{
|
||||
int mitigation = 0;
|
||||
if (m_pp.class_ == WIZARD || m_pp.class_ == MAGICIAN || m_pp.class_ == NECROMANCER || m_pp.class_ == ENCHANTER) {
|
||||
mitigation = (GetSkill(SkillDefense) + itembonuses.HeroicAGI / 10) / 4 + (itembonuses.AC + 1);
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 4 + (itembonuses.AC + 1);
|
||||
mitigation -= 4;
|
||||
}
|
||||
else {
|
||||
mitigation = (GetSkill(SkillDefense) + itembonuses.HeroicAGI / 10) / 3 + ((itembonuses.AC * 4) / 3);
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 3 + ((itembonuses.AC * 4) / 3);
|
||||
if (m_pp.class_ == MONK) {
|
||||
mitigation += GetLevel() * 13 / 10; //the 13/10 might be wrong, but it is close...
|
||||
}
|
||||
}
|
||||
// Shield AC bonus for HeroicSTR
|
||||
if (itembonuses.HeroicSTR) {
|
||||
bool equiped = CastToClient()->m_inv.GetItem(MainSecondary);
|
||||
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary);
|
||||
if (equiped) {
|
||||
uint8 shield = CastToClient()->m_inv.GetItem(MainSecondary)->GetItem()->ItemType;
|
||||
if (shield == ItemTypeShield) {
|
||||
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary)->GetItem()->ItemType;
|
||||
if (shield == EQEmu::item::ItemTypeShield) {
|
||||
mitigation += itembonuses.HeroicSTR / 2;
|
||||
}
|
||||
}
|
||||
@@ -1109,10 +1116,17 @@ int32 Client::GetACMit()
|
||||
|
||||
int32 Client::GetACAvoid()
|
||||
{
|
||||
int32 avoidance = (acmod() + ((GetSkill(SkillDefense) + itembonuses.HeroicAGI / 10) * 16) / 9);
|
||||
int32 avoidance = (acmod() + ((GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) * 16) / 9);
|
||||
if (avoidance < 0) {
|
||||
avoidance = 0;
|
||||
}
|
||||
|
||||
if (RuleB(Character, EnableAvoidanceCap)) {
|
||||
if ((avoidance * 1000 / 847) > RuleI(Character, AvoidanceCap)) {
|
||||
return RuleI(Character, AvoidanceCap);
|
||||
}
|
||||
}
|
||||
|
||||
return (avoidance * 1000 / 847);
|
||||
}
|
||||
|
||||
@@ -1121,7 +1135,7 @@ int32 Client::CalcMaxMana()
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
case 'W': {
|
||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
break;
|
||||
}
|
||||
case 'N': {
|
||||
@@ -1162,7 +1176,7 @@ int32 Client::CalcBaseMana()
|
||||
switch (GetCasterClass()) {
|
||||
case 'I':
|
||||
WisInt = GetINT();
|
||||
if (GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if (WisInt > 201) {
|
||||
@@ -1195,7 +1209,7 @@ int32 Client::CalcBaseMana()
|
||||
break;
|
||||
case 'W':
|
||||
WisInt = GetWIS();
|
||||
if (GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (WisInt > 100) {
|
||||
ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100);
|
||||
if (WisInt > 201) {
|
||||
@@ -1247,8 +1261,8 @@ int32 Client::CalcBaseManaRegen()
|
||||
uint8 clevel = GetLevel();
|
||||
int32 regen = 0;
|
||||
if (IsSitting() || (GetHorseId() != 0)) {
|
||||
if (HasSkill(SkillMeditate)) {
|
||||
regen = (((GetSkill(SkillMeditate) / 10) + (clevel - (clevel / 4))) / 4) + 4;
|
||||
if (HasSkill(EQEmu::skills::SkillMeditate)) {
|
||||
regen = (((GetSkill(EQEmu::skills::SkillMeditate) / 10) + (clevel - (clevel / 4))) / 4) + 4;
|
||||
}
|
||||
else {
|
||||
regen = 2;
|
||||
@@ -1267,11 +1281,11 @@ int32 Client::CalcManaRegen()
|
||||
//this should be changed so we dont med while camping, etc...
|
||||
if (IsSitting() || (GetHorseId() != 0)) {
|
||||
BuffFadeBySitModifier();
|
||||
if (HasSkill(SkillMeditate)) {
|
||||
if (HasSkill(EQEmu::skills::SkillMeditate)) {
|
||||
this->medding = true;
|
||||
regen = (((GetSkill(SkillMeditate) / 10) + (clevel - (clevel / 4))) / 4) + 4;
|
||||
regen = (((GetSkill(EQEmu::skills::SkillMeditate) / 10) + (clevel - (clevel / 4))) / 4) + 4;
|
||||
regen += spellbonuses.ManaRegen + itembonuses.ManaRegen;
|
||||
CheckIncreaseSkill(SkillMeditate, nullptr, -5);
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillMeditate, nullptr, -5);
|
||||
}
|
||||
else {
|
||||
regen = 2 + spellbonuses.ManaRegen + itembonuses.ManaRegen;
|
||||
@@ -1302,11 +1316,11 @@ int32 Client::CalcManaRegenCap()
|
||||
|
||||
uint32 Client::CalcCurrentWeight()
|
||||
{
|
||||
const Item_Struct* TempItem = 0;
|
||||
const EQEmu::ItemBase* TempItem = 0;
|
||||
ItemInst* ins;
|
||||
uint32 Total = 0;
|
||||
int x;
|
||||
for (x = EmuConstants::EQUIPMENT_BEGIN; x <= MainCursor; x++) { // include cursor or not?
|
||||
for (x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::SlotCursor; x++) { // include cursor or not?
|
||||
TempItem = 0;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins) {
|
||||
@@ -1316,7 +1330,7 @@ uint32 Client::CalcCurrentWeight()
|
||||
Total += TempItem->Weight;
|
||||
}
|
||||
}
|
||||
for (x = EmuConstants::GENERAL_BAGS_BEGIN; x <= EmuConstants::GENERAL_BAGS_END; x++) { // include cursor bags or not?
|
||||
for (x = EQEmu::legacy::GENERAL_BAGS_BEGIN; x <= EQEmu::legacy::GENERAL_BAGS_END; x++) { // include cursor bags or not?
|
||||
int TmpWeight = 0;
|
||||
TempItem = 0;
|
||||
ins = GetInv().GetItem(x);
|
||||
@@ -1329,15 +1343,15 @@ uint32 Client::CalcCurrentWeight()
|
||||
if (TmpWeight > 0) {
|
||||
// this code indicates that weight redux bags can only be in the first general inventory slot to be effective...
|
||||
// is this correct? or can we scan for the highest weight redux and use that? (need client verifications)
|
||||
int bagslot = MainGeneral1;
|
||||
int bagslot = EQEmu::legacy::SlotGeneral1;
|
||||
int reduction = 0;
|
||||
for (int m = EmuConstants::GENERAL_BAGS_BEGIN + 10; m <= EmuConstants::GENERAL_BAGS_END; m += 10) { // include cursor bags or not?
|
||||
for (int m = EQEmu::legacy::GENERAL_BAGS_BEGIN + 10; m <= EQEmu::legacy::GENERAL_BAGS_END; m += 10) { // include cursor bags or not?
|
||||
if (x >= m) {
|
||||
bagslot += 1;
|
||||
}
|
||||
}
|
||||
ItemInst* baginst = GetInv().GetItem(bagslot);
|
||||
if (baginst && baginst->GetItem() && baginst->IsType(ItemClassContainer)) {
|
||||
if (baginst && baginst->GetItem() && baginst->IsClassBag()) {
|
||||
reduction = baginst->GetItem()->BagWR;
|
||||
}
|
||||
if (reduction > 0) {
|
||||
@@ -1355,7 +1369,7 @@ uint32 Client::CalcCurrentWeight()
|
||||
This is the ONLY instance I have seen where the client is hard coded to particular Item IDs to set a certain property for an item. It is very odd.
|
||||
*/
|
||||
// SoD+ client has no weight for coin
|
||||
if (EQLimits::CoinHasWeight(GetClientVersion())) {
|
||||
if (EQEmu::behavior::Lookup(EQEmu::versions::ConvertClientVersionToInventoryVersion(ClientVersion()))->CoinHasWeight) {
|
||||
Total += (m_pp.platinum + m_pp.gold + m_pp.silver + m_pp.copper) / 4;
|
||||
}
|
||||
float Packrat = (float)spellbonuses.Packrat + (float)aabonuses.Packrat + (float)itembonuses.Packrat;
|
||||
@@ -1633,13 +1647,19 @@ int32 Client::CalcMR()
|
||||
MR = 30;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
MR = 35;
|
||||
{
|
||||
MR = 25;
|
||||
if (GetDrakkinHeritage() == 2)
|
||||
MR += 10;
|
||||
else if (GetDrakkinHeritage() == 5)
|
||||
MR += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MR = 20;
|
||||
}
|
||||
MR += itembonuses.MR + spellbonuses.MR + aabonuses.MR;
|
||||
if (GetClass() == WARRIOR) {
|
||||
if (GetClass() == WARRIOR || GetClass() == BERSERKER) {
|
||||
MR += GetLevel() / 2;
|
||||
}
|
||||
if (MR < 1) {
|
||||
@@ -1701,8 +1721,14 @@ int32 Client::CalcFR()
|
||||
FR = 25;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
{
|
||||
FR = 25;
|
||||
if (GetDrakkinHeritage() == 0)
|
||||
FR += 10;
|
||||
else if (GetDrakkinHeritage() == 5)
|
||||
FR += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FR = 20;
|
||||
}
|
||||
@@ -1714,6 +1740,13 @@ int32 Client::CalcFR()
|
||||
FR += l - 49;
|
||||
}
|
||||
}
|
||||
if (c == MONK) {
|
||||
FR += 8;
|
||||
int l = GetLevel();
|
||||
if (l > 49) {
|
||||
FR += l - 49;
|
||||
}
|
||||
}
|
||||
FR += itembonuses.FR + spellbonuses.FR + aabonuses.FR;
|
||||
if (FR < 1) {
|
||||
FR = 1;
|
||||
@@ -1774,12 +1807,24 @@ int32 Client::CalcDR()
|
||||
DR = 15;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
{
|
||||
DR = 15;
|
||||
if (GetDrakkinHeritage() == 1)
|
||||
DR += 10;
|
||||
else if (GetDrakkinHeritage() == 5)
|
||||
DR += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DR = 15;
|
||||
}
|
||||
int c = GetClass();
|
||||
// the monk one is part of base resist
|
||||
if (c == MONK) {
|
||||
int l = GetLevel();
|
||||
if (l > 50)
|
||||
DR += l - 50;
|
||||
}
|
||||
if (c == PALADIN) {
|
||||
DR += 8;
|
||||
int l = GetLevel();
|
||||
@@ -1787,7 +1832,7 @@ int32 Client::CalcDR()
|
||||
DR += l - 49;
|
||||
}
|
||||
}
|
||||
else if (c == SHADOWKNIGHT) {
|
||||
else if (c == SHADOWKNIGHT || c == BEASTLORD) {
|
||||
DR += 4;
|
||||
int l = GetLevel();
|
||||
if (l > 49) {
|
||||
@@ -1854,12 +1899,24 @@ int32 Client::CalcPR()
|
||||
PR = 30;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
{
|
||||
PR = 15;
|
||||
if (GetDrakkinHeritage() == 3)
|
||||
PR += 10;
|
||||
else if (GetDrakkinHeritage() == 5)
|
||||
PR += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PR = 15;
|
||||
}
|
||||
int c = GetClass();
|
||||
// this monk bonus is part of the base
|
||||
if (c == MONK) {
|
||||
int l = GetLevel();
|
||||
if (l > 50)
|
||||
PR += l - 50;
|
||||
}
|
||||
if (c == ROGUE) {
|
||||
PR += 8;
|
||||
int l = GetLevel();
|
||||
@@ -1934,13 +1991,19 @@ int32 Client::CalcCR()
|
||||
CR = 25;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
{
|
||||
CR = 25;
|
||||
if (GetDrakkinHeritage() == 4)
|
||||
CR += 10;
|
||||
else if (GetDrakkinHeritage() == 5)
|
||||
CR += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CR = 25;
|
||||
}
|
||||
int c = GetClass();
|
||||
if (c == RANGER) {
|
||||
if (c == RANGER || c == BEASTLORD) {
|
||||
CR += 4;
|
||||
int l = GetLevel();
|
||||
if (l > 49) {
|
||||
@@ -1974,101 +2037,99 @@ int32 Client::CalcATK()
|
||||
|
||||
uint32 Mob::GetInstrumentMod(uint16 spell_id) const
|
||||
{
|
||||
if (GetClass() != BARD) {
|
||||
if (GetClass() != BARD || spells[spell_id].IsDisciplineBuff) // Puretone is Singing but doesn't get any mod
|
||||
return 10;
|
||||
}
|
||||
|
||||
uint32 effectmod = 10;
|
||||
int effectmodcap = RuleI(Character, BaseInstrumentSoftCap);
|
||||
//this should never use spell modifiers...
|
||||
//if a spell grants better modifers, they are copied into the item mods
|
||||
//because the spells are supposed to act just like having the intrument.
|
||||
//item mods are in 10ths of percent increases
|
||||
int effectmodcap = 0;
|
||||
bool nocap = false;
|
||||
if (RuleB(Character, UseSpellFileSongCap)) {
|
||||
effectmodcap = spells[spell_id].songcap / 10;
|
||||
// this looks a bit weird, but easiest way I could think to keep both systems working
|
||||
if (effectmodcap == 0)
|
||||
nocap = true;
|
||||
else
|
||||
effectmodcap += 10;
|
||||
} else {
|
||||
effectmodcap = RuleI(Character, BaseInstrumentSoftCap);
|
||||
}
|
||||
// this should never use spell modifiers...
|
||||
// if a spell grants better modifers, they are copied into the item mods
|
||||
// because the spells are supposed to act just like having the intrument.
|
||||
// item mods are in 10ths of percent increases
|
||||
// clickies (Symphony of Battle) that have a song skill don't get AA bonus for some reason
|
||||
// but clickies that are songs (selo's on Composers Greaves) do get AA mod as well
|
||||
switch (spells[spell_id].skill) {
|
||||
case SkillPercussionInstruments:
|
||||
if (itembonuses.percussionMod == 0 && spellbonuses.percussionMod == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (GetSkill(SkillPercussionInstruments) == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (itembonuses.percussionMod > spellbonuses.percussionMod) {
|
||||
effectmod = itembonuses.percussionMod;
|
||||
}
|
||||
else {
|
||||
effectmod = spellbonuses.percussionMod;
|
||||
}
|
||||
effectmod += aabonuses.percussionMod;
|
||||
break;
|
||||
case SkillStringedInstruments:
|
||||
if (itembonuses.stringedMod == 0 && spellbonuses.stringedMod == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (GetSkill(SkillStringedInstruments) == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (itembonuses.stringedMod > spellbonuses.stringedMod) {
|
||||
effectmod = itembonuses.stringedMod;
|
||||
}
|
||||
else {
|
||||
effectmod = spellbonuses.stringedMod;
|
||||
}
|
||||
effectmod += aabonuses.stringedMod;
|
||||
break;
|
||||
case SkillWindInstruments:
|
||||
if (itembonuses.windMod == 0 && spellbonuses.windMod == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (GetSkill(SkillWindInstruments) == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (itembonuses.windMod > spellbonuses.windMod) {
|
||||
effectmod = itembonuses.windMod;
|
||||
}
|
||||
else {
|
||||
effectmod = spellbonuses.windMod;
|
||||
}
|
||||
effectmod += aabonuses.windMod;
|
||||
break;
|
||||
case SkillBrassInstruments:
|
||||
if (itembonuses.brassMod == 0 && spellbonuses.brassMod == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (GetSkill(SkillBrassInstruments) == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (itembonuses.brassMod > spellbonuses.brassMod) {
|
||||
effectmod = itembonuses.brassMod;
|
||||
}
|
||||
else {
|
||||
effectmod = spellbonuses.brassMod;
|
||||
}
|
||||
effectmod += aabonuses.brassMod;
|
||||
break;
|
||||
case SkillSinging:
|
||||
if (itembonuses.singingMod == 0 && spellbonuses.singingMod == 0) {
|
||||
effectmod = 10;
|
||||
}
|
||||
else if (itembonuses.singingMod > spellbonuses.singingMod) {
|
||||
effectmod = itembonuses.singingMod;
|
||||
}
|
||||
else {
|
||||
effectmod = spellbonuses.singingMod;
|
||||
}
|
||||
effectmod += aabonuses.singingMod + spellbonuses.Amplification;
|
||||
break;
|
||||
default:
|
||||
case EQEmu::skills::SkillPercussionInstruments:
|
||||
if (itembonuses.percussionMod == 0 && spellbonuses.percussionMod == 0)
|
||||
effectmod = 10;
|
||||
break;
|
||||
}
|
||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
||||
if (effectmod < 10) {
|
||||
else if (GetSkill(EQEmu::skills::SkillPercussionInstruments) == 0)
|
||||
effectmod = 10;
|
||||
else if (itembonuses.percussionMod > spellbonuses.percussionMod)
|
||||
effectmod = itembonuses.percussionMod;
|
||||
else
|
||||
effectmod = spellbonuses.percussionMod;
|
||||
if (IsBardSong(spell_id))
|
||||
effectmod += aabonuses.percussionMod;
|
||||
break;
|
||||
case EQEmu::skills::SkillStringedInstruments:
|
||||
if (itembonuses.stringedMod == 0 && spellbonuses.stringedMod == 0)
|
||||
effectmod = 10;
|
||||
else if (GetSkill(EQEmu::skills::SkillStringedInstruments) == 0)
|
||||
effectmod = 10;
|
||||
else if (itembonuses.stringedMod > spellbonuses.stringedMod)
|
||||
effectmod = itembonuses.stringedMod;
|
||||
else
|
||||
effectmod = spellbonuses.stringedMod;
|
||||
if (IsBardSong(spell_id))
|
||||
effectmod += aabonuses.stringedMod;
|
||||
break;
|
||||
case EQEmu::skills::SkillWindInstruments:
|
||||
if (itembonuses.windMod == 0 && spellbonuses.windMod == 0)
|
||||
effectmod = 10;
|
||||
else if (GetSkill(EQEmu::skills::SkillWindInstruments) == 0)
|
||||
effectmod = 10;
|
||||
else if (itembonuses.windMod > spellbonuses.windMod)
|
||||
effectmod = itembonuses.windMod;
|
||||
else
|
||||
effectmod = spellbonuses.windMod;
|
||||
if (IsBardSong(spell_id))
|
||||
effectmod += aabonuses.windMod;
|
||||
break;
|
||||
case EQEmu::skills::SkillBrassInstruments:
|
||||
if (itembonuses.brassMod == 0 && spellbonuses.brassMod == 0)
|
||||
effectmod = 10;
|
||||
else if (GetSkill(EQEmu::skills::SkillBrassInstruments) == 0)
|
||||
effectmod = 10;
|
||||
else if (itembonuses.brassMod > spellbonuses.brassMod)
|
||||
effectmod = itembonuses.brassMod;
|
||||
else
|
||||
effectmod = spellbonuses.brassMod;
|
||||
if (IsBardSong(spell_id))
|
||||
effectmod += aabonuses.brassMod;
|
||||
break;
|
||||
case EQEmu::skills::SkillSinging:
|
||||
if (itembonuses.singingMod == 0 && spellbonuses.singingMod == 0)
|
||||
effectmod = 10;
|
||||
else if (itembonuses.singingMod > spellbonuses.singingMod)
|
||||
effectmod = itembonuses.singingMod;
|
||||
else
|
||||
effectmod = spellbonuses.singingMod;
|
||||
if (IsBardSong(spell_id))
|
||||
effectmod += aabonuses.singingMod + spellbonuses.Amplification;
|
||||
break;
|
||||
default:
|
||||
effectmod = 10;
|
||||
return effectmod;
|
||||
}
|
||||
if (effectmod > effectmodcap) {
|
||||
if (!RuleB(Character, UseSpellFileSongCap))
|
||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap;
|
||||
if (effectmod < 10)
|
||||
effectmod = 10;
|
||||
if (!nocap && effectmod > effectmodcap) // if the cap is calculated to be 0 using new rules, no cap.
|
||||
effectmod = effectmodcap;
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n",
|
||||
GetName(), spell_id, effectmod, effectmodcap);
|
||||
Log.Out(Logs::Detail, Logs::Spells, "%s::GetInstrumentMod() spell=%d mod=%d modcap=%d\n", GetName(), spell_id,
|
||||
effectmod, effectmodcap);
|
||||
return effectmod;
|
||||
}
|
||||
|
||||
@@ -2093,7 +2154,7 @@ void Client::CalcMaxEndurance()
|
||||
int32 Client::CalcBaseEndurance()
|
||||
{
|
||||
int32 base_end = 0;
|
||||
if (GetClientVersion() >= ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) {
|
||||
double heroic_stats = (GetHeroicSTR() + GetHeroicSTA() + GetHeroicDEX() + GetHeroicAGI()) / 4.0f;
|
||||
double stats = (GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4.0f;
|
||||
if (stats > 201.0f) {
|
||||
@@ -2158,12 +2219,12 @@ int Client::GetRawACNoShield(int &shield_ac) const
|
||||
{
|
||||
int ac = itembonuses.AC + spellbonuses.AC + aabonuses.AC;
|
||||
shield_ac = 0;
|
||||
const ItemInst *inst = m_inv.GetItem(MainSecondary);
|
||||
const ItemInst *inst = m_inv.GetItem(EQEmu::legacy::SlotSecondary);
|
||||
if (inst) {
|
||||
if (inst->GetItem()->ItemType == ItemTypeShield) {
|
||||
if (inst->GetItem()->ItemType == EQEmu::item::ItemTypeShield) {
|
||||
ac -= inst->GetItem()->AC;
|
||||
shield_ac = inst->GetItem()->AC;
|
||||
for (uint8 i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
for (uint8 i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
if (inst->GetAugment(i)) {
|
||||
ac -= inst->GetAugment(i)->GetItem()->AC;
|
||||
shield_ac += inst->GetAugment(i)->GetItem()->AC;
|
||||
|
||||
+904
-747
File diff suppressed because it is too large
Load Diff
@@ -218,6 +218,8 @@
|
||||
void Handle_OP_PetitionRefresh(const EQApplicationPacket *app);
|
||||
void Handle_OP_PetitionResolve(const EQApplicationPacket *app);
|
||||
void Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app);
|
||||
void Handle_OP_PlayerStateAdd(const EQApplicationPacket *app);
|
||||
void Handle_OP_PlayerStateRemove(const EQApplicationPacket *app);
|
||||
void Handle_OP_PickPocket(const EQApplicationPacket *app);
|
||||
void Handle_OP_PopupResponse(const EQApplicationPacket *app);
|
||||
void Handle_OP_PotionBelt(const EQApplicationPacket *app);
|
||||
@@ -290,6 +292,8 @@
|
||||
void Handle_OP_WearChange(const EQApplicationPacket *app);
|
||||
void Handle_OP_WhoAllRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetOpen(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
|
||||
void Handle_OP_ZoneChange(const EQApplicationPacket *app);
|
||||
void Handle_OP_ResetAA(const EQApplicationPacket *app);
|
||||
|
||||
+167
-278
@@ -26,8 +26,8 @@
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
extern QueryServ* QServ;
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern PetitionList petition_list;
|
||||
extern EntityList entity_list;
|
||||
@@ -66,7 +66,7 @@ bool Client::Process() {
|
||||
if(Connected() || IsLD())
|
||||
{
|
||||
// try to send all packets that weren't sent before
|
||||
if(!IsLD() && zoneinpacket_timer.Check())
|
||||
if (!IsLD() && zoneinpacket_timer.Check())
|
||||
{
|
||||
SendAllPackets();
|
||||
}
|
||||
@@ -126,17 +126,19 @@ bool Client::Process() {
|
||||
HandleRespawnFromHover(0);
|
||||
}
|
||||
|
||||
if(IsTracking() && (GetClientVersion() >= ClientVersion::SoD) && TrackingTimer.Check())
|
||||
if (IsTracking() && (ClientVersion() >= EQEmu::versions::ClientVersion::SoD) && TrackingTimer.Check())
|
||||
DoTracking();
|
||||
|
||||
if(hpupdate_timer.Check())
|
||||
// SendHPUpdate calls hpupdate_timer.Start so it can delay this timer, so lets not reset with the check
|
||||
// since the function will anyways
|
||||
if(hpupdate_timer.Check(false))
|
||||
SendHPUpdate();
|
||||
|
||||
if(mana_timer.Check())
|
||||
SendManaUpdatePacket();
|
||||
|
||||
if(dead && dead_timer.Check()) {
|
||||
database.MoveCharacterToZone(GetName(), database.GetZoneName(m_pp.binds[0].zoneId));
|
||||
if(dead && dead_timer.Check()) {
|
||||
database.MoveCharacterToZone(GetName(), database.GetZoneName(m_pp.binds[0].zoneId));
|
||||
|
||||
m_pp.zone_id = m_pp.binds[0].zoneId;
|
||||
m_pp.zoneInstance = m_pp.binds[0].instance_id;
|
||||
@@ -197,10 +199,8 @@ bool Client::Process() {
|
||||
instalog = true;
|
||||
}
|
||||
|
||||
if (IsStunned() && stunned_timer.Check()) {
|
||||
this->stunned = false;
|
||||
this->stunned_timer.Disable();
|
||||
}
|
||||
if (IsStunned() && stunned_timer.Check())
|
||||
Mob::UnStun();
|
||||
|
||||
if(!m_CheatDetectMoved)
|
||||
{
|
||||
@@ -262,7 +262,7 @@ bool Client::Process() {
|
||||
}
|
||||
|
||||
if(light_update_timer.Check()) {
|
||||
|
||||
|
||||
UpdateEquipmentLight();
|
||||
if(UpdateActiveLight()) {
|
||||
SendAppearancePacket(AT_Light, GetActiveLightType());
|
||||
@@ -296,10 +296,10 @@ bool Client::Process() {
|
||||
}
|
||||
|
||||
if(AutoFireEnabled()){
|
||||
ItemInst *ranged = GetInv().GetItem(MainRange);
|
||||
ItemInst *ranged = GetInv().GetItem(EQEmu::legacy::SlotRange);
|
||||
if(ranged)
|
||||
{
|
||||
if(ranged->GetItem() && ranged->GetItem()->ItemType == ItemTypeBow){
|
||||
if (ranged->GetItem() && ranged->GetItem()->ItemType == EQEmu::item::ItemTypeBow){
|
||||
if(ranged_timer.Check(false)){
|
||||
if(GetTarget() && (GetTarget()->IsNPC() || GetTarget()->IsClient())){
|
||||
if(GetTarget()->InFrontMob(this, GetTarget()->GetX(), GetTarget()->GetY())){
|
||||
@@ -319,7 +319,7 @@ bool Client::Process() {
|
||||
ranged_timer.Start();
|
||||
}
|
||||
}
|
||||
else if(ranged->GetItem() && (ranged->GetItem()->ItemType == ItemTypeLargeThrowing || ranged->GetItem()->ItemType == ItemTypeSmallThrowing)){
|
||||
else if (ranged->GetItem() && (ranged->GetItem()->ItemType == EQEmu::item::ItemTypeLargeThrowing || ranged->GetItem()->ItemType == EQEmu::item::ItemTypeSmallThrowing)){
|
||||
if(ranged_timer.Check(false)){
|
||||
if(GetTarget() && (GetTarget()->IsNPC() || GetTarget()->IsClient())){
|
||||
if(GetTarget()->InFrontMob(this, GetTarget()->GetX(), GetTarget()->GetY())){
|
||||
@@ -391,73 +391,12 @@ bool Client::Process() {
|
||||
}
|
||||
else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP
|
||||
{
|
||||
if(CheckAAEffect(aaEffectRampage))
|
||||
{
|
||||
ItemInst *wpn = GetInv().GetItem(EQEmu::legacy::SlotPrimary);
|
||||
TryWeaponProc(wpn, auto_attack_target, EQEmu::legacy::SlotPrimary);
|
||||
|
||||
DoAttackRounds(auto_attack_target, EQEmu::legacy::SlotPrimary);
|
||||
if (CheckAATimer(aaTimerRampage))
|
||||
entity_list.AEAttack(this, 30);
|
||||
} else {
|
||||
Attack(auto_attack_target, MainPrimary); // Kaiyodo - added attacking hand to arguments
|
||||
}
|
||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
||||
|
||||
bool tripleAttackSuccess = false;
|
||||
if( auto_attack_target && CanThisClassDoubleAttack() ) {
|
||||
|
||||
CheckIncreaseSkill(SkillDoubleAttack, auto_attack_target, -10);
|
||||
if(CheckDoubleAttack()) {
|
||||
//should we allow rampage on double attack?
|
||||
if(CheckAAEffect(aaEffectRampage)) {
|
||||
entity_list.AEAttack(this, 30);
|
||||
} else {
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
//triple attack: rangers, monks, warriors, berserkers over level 60
|
||||
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
|
||||
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
|
||||
&& CheckDoubleAttack(true))
|
||||
{
|
||||
tripleAttackSuccess = true;
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
|
||||
//quad attack, does this belong here??
|
||||
if(GetSpecialAbility(SPECATK_QUAD) && CheckDoubleAttack(true))
|
||||
{
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
|
||||
int16 flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||
|
||||
if (auto_attack_target && flurrychance)
|
||||
{
|
||||
if(zone->random.Int(0, 99) < flurrychance)
|
||||
{
|
||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
||||
|
||||
if (auto_attack_target && ExtraAttackChanceBonus) {
|
||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||
if(wpn){
|
||||
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
|
||||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
||||
wpn->GetItem()->ItemType == ItemType2HPiercing )
|
||||
{
|
||||
if(zone->random.Int(0, 99) < ExtraAttackChanceBonus)
|
||||
{
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,32 +428,12 @@ bool Client::Process() {
|
||||
//you can't see your target
|
||||
}
|
||||
else if(auto_attack_target->GetHP() > -10) {
|
||||
float DualWieldProbability = 0.0f;
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillDualWield, auto_attack_target, -10);
|
||||
if (CheckDualWield()) {
|
||||
ItemInst *wpn = GetInv().GetItem(EQEmu::legacy::SlotSecondary);
|
||||
TryWeaponProc(wpn, auto_attack_target, EQEmu::legacy::SlotSecondary);
|
||||
|
||||
int16 Ambidexterity = aabonuses.Ambidexterity + spellbonuses.Ambidexterity + itembonuses.Ambidexterity;
|
||||
DualWieldProbability = (GetSkill(SkillDualWield) + GetLevel() + Ambidexterity) / 400.0f; // 78.0 max
|
||||
int16 DWBonus = spellbonuses.DualWieldChance + itembonuses.DualWieldChance;
|
||||
DualWieldProbability += DualWieldProbability*float(DWBonus)/ 100.0f;
|
||||
|
||||
float random = zone->random.Real(0, 1);
|
||||
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
||||
if (random < DualWieldProbability){ // Max 78% of DW
|
||||
if(CheckAAEffect(aaEffectRampage)) {
|
||||
entity_list.AEAttack(this, 30, MainSecondary);
|
||||
} else {
|
||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
||||
}
|
||||
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
||||
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
||||
|
||||
if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
|
||||
if(CheckAAEffect(aaEffectRampage)) {
|
||||
entity_list.AEAttack(this, 30, MainSecondary);
|
||||
} else {
|
||||
if(auto_attack_target && auto_attack_target->GetHP() > -10)
|
||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
||||
}
|
||||
}
|
||||
DoAttackRounds(auto_attack_target, EQEmu::legacy::SlotSecondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,9 +441,7 @@ bool Client::Process() {
|
||||
if (position_timer.Check()) {
|
||||
if (IsAIControlled())
|
||||
{
|
||||
if(IsMoving())
|
||||
SendPosUpdate(2);
|
||||
else
|
||||
if(!IsMoving())
|
||||
{
|
||||
animation = 0;
|
||||
m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w);
|
||||
@@ -562,7 +479,7 @@ bool Client::Process() {
|
||||
}
|
||||
|
||||
ProjectileAttack();
|
||||
|
||||
|
||||
if(spellbonuses.GravityEffect == 1) {
|
||||
if(gravity_timer.Check())
|
||||
DoGravityEffect();
|
||||
@@ -707,7 +624,7 @@ bool Client::Process() {
|
||||
{
|
||||
//client logged out or errored out
|
||||
//ResetTrade();
|
||||
if (client_state != CLIENT_KICKED) {
|
||||
if (client_state != CLIENT_KICKED && !zoning && !instalog) {
|
||||
Save();
|
||||
}
|
||||
|
||||
@@ -793,7 +710,7 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
||||
Mob *Other = trade->With();
|
||||
if(Other)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client disconnected during a trade. Returning their items.");
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client disconnected during a trade. Returning their items.");
|
||||
FinishTrade(this);
|
||||
|
||||
if(Other->IsClient())
|
||||
@@ -809,27 +726,22 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
||||
/* Remove ourself from all proximities */
|
||||
ClearAllProximities();
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
|
||||
auto outapp = new EQApplicationPacket(OP_LogoutReply);
|
||||
FastQueuePacket(&outapp);
|
||||
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
// Sends the client complete inventory used in character login
|
||||
|
||||
// DO WE STILL NEED THE 'ITEMCOMBINED' CONDITIONAL CODE?
|
||||
|
||||
//#ifdef ITEMCOMBINED
|
||||
void Client::BulkSendInventoryItems() {
|
||||
int16 slot_id = 0;
|
||||
|
||||
void Client::BulkSendInventoryItems()
|
||||
{
|
||||
// LINKDEAD TRADE ITEMS
|
||||
// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks
|
||||
for(slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_END; slot_id++) {
|
||||
for (int16 slot_id = EQEmu::legacy::TRADE_BEGIN; slot_id <= EQEmu::legacy::TRADE_END; slot_id++) {
|
||||
ItemInst* inst = m_inv.PopItem(slot_id);
|
||||
if(inst) {
|
||||
bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
|
||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow);
|
||||
bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
|
||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
|
||||
Log.Out(Logs::Detail, Logs::Inventory, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id);
|
||||
PutItemInInventory(free_slot_id, *inst, false);
|
||||
database.SaveInventory(character_id, nullptr, slot_id);
|
||||
@@ -838,141 +750,87 @@ void Client::BulkSendInventoryItems() {
|
||||
}
|
||||
|
||||
bool deletenorent = database.NoRentExpired(GetName());
|
||||
if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items
|
||||
if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
|
||||
if (RuleB(Inventory, TransformSummonedBags))
|
||||
DisenchantSummonedBags(false);
|
||||
RemoveNoRent(false);
|
||||
}
|
||||
|
||||
RemoveDuplicateLore(false);
|
||||
MoveSlotNotAllowed(false);
|
||||
|
||||
// The previous three method calls took care of moving/removing expired/illegal item placements
|
||||
EQEmu::OutBuffer ob;
|
||||
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
||||
|
||||
//TODO: this function is just retarded... it re-allocates the buffer for every
|
||||
//new item. It should be changed to loop through once, gather the
|
||||
//lengths, and item packet pointers into an array (fixed length), and
|
||||
//then loop again to build the packet.
|
||||
//EQApplicationPacket *packets[50];
|
||||
//unsigned long buflen = 0;
|
||||
//unsigned long pos = 0;
|
||||
//memset(packets, 0, sizeof(packets));
|
||||
//foreach item in the invendor sections
|
||||
// packets[pos++] = ReturnItemPacket(...)
|
||||
// buflen += temp->size
|
||||
//...
|
||||
//allocat the buffer
|
||||
//for r from 0 to pos
|
||||
// put pos[r]->pBuffer into the buffer
|
||||
//for r from 0 to pos
|
||||
// safe_delete(pos[r]);
|
||||
|
||||
uint32 size = 0;
|
||||
uint16 i = 0;
|
||||
std::map<uint16, std::string> ser_items;
|
||||
std::map<uint16, std::string>::iterator itr;
|
||||
|
||||
//Inventory items
|
||||
for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) {
|
||||
// Possessions items
|
||||
for (int16 slot_id = SLOT_BEGIN; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if(inst) {
|
||||
std::string packet = inst->Serialize(slot_id);
|
||||
ser_items[i++] = packet;
|
||||
size += packet.length();
|
||||
}
|
||||
if (!inst)
|
||||
continue;
|
||||
|
||||
inst->Serialize(ob, slot_id);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
|
||||
// Power Source
|
||||
if(GetClientVersion() >= ClientVersion::SoF) {
|
||||
const ItemInst* inst = m_inv[MainPowerSource];
|
||||
if(inst) {
|
||||
std::string packet = inst->Serialize(MainPowerSource);
|
||||
ser_items[i++] = packet;
|
||||
size += packet.length();
|
||||
// PowerSource item
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
const ItemInst* inst = m_inv[EQEmu::legacy::SlotPowerSource];
|
||||
if (inst) {
|
||||
inst->Serialize(ob, EQEmu::legacy::SlotPowerSource);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::legacy::SlotPowerSource);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
}
|
||||
|
||||
// Bank items
|
||||
for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) {
|
||||
for (int16 slot_id = EQEmu::legacy::BANK_BEGIN; slot_id <= EQEmu::legacy::BANK_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if(inst) {
|
||||
std::string packet = inst->Serialize(slot_id);
|
||||
ser_items[i++] = packet;
|
||||
size += packet.length();
|
||||
}
|
||||
if (!inst)
|
||||
continue;
|
||||
|
||||
inst->Serialize(ob, slot_id);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
|
||||
// Shared Bank items
|
||||
for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; slot_id++) {
|
||||
// SharedBank items
|
||||
for (int16 slot_id = EQEmu::legacy::SHARED_BANK_BEGIN; slot_id <= EQEmu::legacy::SHARED_BANK_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if(inst) {
|
||||
std::string packet = inst->Serialize(slot_id);
|
||||
ser_items[i++] = packet;
|
||||
size += packet.length();
|
||||
}
|
||||
if (!inst)
|
||||
continue;
|
||||
|
||||
inst->Serialize(ob, slot_id);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, size);
|
||||
uchar* ptr = outapp->pBuffer;
|
||||
for(itr = ser_items.begin(); itr != ser_items.end(); ++itr){
|
||||
int length = itr->second.length();
|
||||
if(length > 5) {
|
||||
memcpy(ptr, itr->second.c_str(), length);
|
||||
ptr += length;
|
||||
}
|
||||
}
|
||||
auto outapp = new EQApplicationPacket(OP_CharInventory);
|
||||
outapp->size = ob.size();
|
||||
outapp->pBuffer = ob.detach();
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
/*#else
|
||||
void Client::BulkSendInventoryItems()
|
||||
{
|
||||
// Search all inventory buckets for items
|
||||
bool deletenorent=database.NoRentExpired(GetName());
|
||||
// Worn items and Inventory items
|
||||
int16 slot_id = 0;
|
||||
if(deletenorent){//client was offline for more than 30 minutes, delete no rent items
|
||||
RemoveNoRent();
|
||||
}
|
||||
for (slot_id=EmuConstants::POSSESSIONS_BEGIN; slot_id<=EmuConstants::POSSESSIONS_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst){
|
||||
SendItemPacket(slot_id, inst, ItemPacketCharInventory);
|
||||
}
|
||||
}
|
||||
// Bank items
|
||||
for (slot_id=EmuConstants::BANK_BEGIN; slot_id<=EmuConstants::BANK_END; slot_id++) { // 2015...
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst){
|
||||
SendItemPacket(slot_id, inst, ItemPacketCharInventory);
|
||||
}
|
||||
}
|
||||
|
||||
// Shared Bank items
|
||||
for (slot_id=EmuConstants::SHARED_BANK_BEGIN; slot_id<=EmuConstants::SHARED_BANK_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst){
|
||||
SendItemPacket(slot_id, inst, ItemPacketCharInventory);
|
||||
}
|
||||
}
|
||||
|
||||
// LINKDEAD TRADE ITEMS
|
||||
// If player went LD during a trade, they have items in the trade inventory
|
||||
// slots. These items are now being put into their inventory (then queue up on cursor)
|
||||
for (int16 trade_slot_id=EmuConstants::TRADE_BEGIN; trade_slot_id<=EmuConstants::TRADE_END; trade_slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst) {
|
||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size);
|
||||
DeleteItemInInventory(trade_slot_id, 0, false);
|
||||
PutItemInInventory(free_slot_id, *inst, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif*/
|
||||
|
||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
const Item_Struct* handyitem = nullptr;
|
||||
const EQEmu::ItemBase* handyitem = nullptr;
|
||||
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
|
||||
if (m_ClientVersionBit & BIT_RoFAndLater) { // RoF+ can send 200 items
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater) { // RoF+ can send 200 items
|
||||
numItemSlots = 200;
|
||||
}
|
||||
const Item_Struct *item;
|
||||
const EQEmu::ItemBase *item;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
Mob* merch = entity_list.GetMobByNpcTypeID(npcid);
|
||||
@@ -1011,7 +869,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||
else
|
||||
handychance--;
|
||||
int charges = 1;
|
||||
if (item->ItemClass == ItemClassCommon)
|
||||
if (item->IsClassCommon())
|
||||
charges = item->MaxCharges;
|
||||
ItemInst* inst = database.CreateItem(item, charges);
|
||||
if (inst) {
|
||||
@@ -1158,7 +1016,10 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I
|
||||
if((SpellEffectDescNum == 82) || (SpellEffectDescNum == 39067)) {
|
||||
SetMana(0);
|
||||
SetHP(GetMaxHP()/5);
|
||||
SpellOnTarget(756, this); // Rezz effects
|
||||
int rez_eff = 756;
|
||||
if (GetRace() == BARBARIAN || GetRace() == DWARF || GetRace() == TROLL || GetRace() == OGRE)
|
||||
rez_eff = 757;
|
||||
SpellOnTarget(rez_eff, this); // Rezz effects
|
||||
}
|
||||
else {
|
||||
SetMana(GetMaxMana());
|
||||
@@ -1226,16 +1087,21 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
|
||||
switch(memspell->scribing)
|
||||
{
|
||||
case memSpellScribing: { // scribing spell to book
|
||||
const ItemInst* inst = m_inv[MainCursor];
|
||||
const ItemInst* inst = m_inv[EQEmu::legacy::SlotCursor];
|
||||
|
||||
if(inst && inst->IsType(ItemClassCommon))
|
||||
if (inst && inst->IsClassCommon())
|
||||
{
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const EQEmu::ItemBase* item = inst->GetItem();
|
||||
|
||||
if (RuleB(Character, RestrictSpellScribing) && !item->IsEquipable(GetRace(), GetClass())) {
|
||||
Message_StringID(13, CANNOT_USE_ITEM);
|
||||
break;
|
||||
}
|
||||
|
||||
if(item && item->Scroll.Effect == (int32)(memspell->spell_id))
|
||||
{
|
||||
ScribeSpell(memspell->spell_id, memspell->slot);
|
||||
DeleteItemInInventory(MainCursor, 1, true);
|
||||
DeleteItemInInventory(EQEmu::legacy::SlotCursor, 1, true);
|
||||
}
|
||||
else
|
||||
Message(0,"Scribing spell: inst exists but item does not or spell ids do not match.");
|
||||
@@ -1264,11 +1130,26 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
|
||||
Save();
|
||||
}
|
||||
|
||||
void Client::CancelSneakHide()
|
||||
{
|
||||
if (hidden || improved_hidden) {
|
||||
auto app = new EQApplicationPacket(OP_CancelSneakHide, 0);
|
||||
FastQueuePacket(&app);
|
||||
// SoF and Tit send back a OP_SpawnAppearance turning off AT_Invis
|
||||
// so we need to handle our sneaking flag only
|
||||
// The later clients send back a OP_Hide (this has a size but data is 0)
|
||||
// as well as OP_SpawnAppearance with AT_Invis and one with AT_Sneak
|
||||
// So we don't have to handle any of those flags
|
||||
if (ClientVersionBit() & EQEmu::versions::bit_SoFAndEarlier)
|
||||
sneaking = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::BreakInvis()
|
||||
{
|
||||
if (invisible)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||
sa_out->spawn_id = GetID();
|
||||
sa_out->type = 0x03;
|
||||
@@ -1581,7 +1462,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
|
||||
trade->sp, trade->cp
|
||||
);
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TradeCoins,sizeof(TradeCoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_TradeCoins, sizeof(TradeCoin_Struct));
|
||||
TradeCoin_Struct* tcs = (TradeCoin_Struct*)outapp->pBuffer;
|
||||
tcs->trader = trader->GetID();
|
||||
tcs->slot = mc->cointype2;
|
||||
@@ -1618,15 +1499,20 @@ void Client::OPGMTraining(const EQApplicationPacket *app)
|
||||
// if this for-loop acts up again (crashes linux), try enabling the before and after #pragmas
|
||||
//#pragma GCC push_options
|
||||
//#pragma GCC optimize ("O0")
|
||||
for (int sk = Skill1HBlunt; sk <= HIGHEST_SKILL; ++sk) {
|
||||
if(sk == SkillTinkering && GetRace() != GNOME) {
|
||||
for (int sk = EQEmu::skills::Skill1HBlunt; sk <= EQEmu::skills::HIGHEST_SKILL; ++sk) {
|
||||
if (sk == EQEmu::skills::SkillTinkering && GetRace() != GNOME) {
|
||||
gmtrain->skills[sk] = 0; //Non gnomes can't tinker!
|
||||
} else {
|
||||
gmtrain->skills[sk] = GetMaxSkillAfterSpecializationRules((SkillUseTypes)sk, MaxSkill((SkillUseTypes)sk, GetClass(), RuleI(Character, MaxLevel)));
|
||||
gmtrain->skills[sk] = GetMaxSkillAfterSpecializationRules((EQEmu::skills::SkillType)sk, MaxSkill((EQEmu::skills::SkillType)sk, GetClass(), RuleI(Character, MaxLevel)));
|
||||
//this is the highest level that the trainer can train you to, this is enforced clientside so we can't just
|
||||
//Set it to 1 with CanHaveSkill or you wont be able to train past 1.
|
||||
}
|
||||
}
|
||||
|
||||
if (ClientVersion() < EQEmu::versions::ClientVersion::RoF2 && GetClass() == BERSERKER) {
|
||||
gmtrain->skills[EQEmu::skills::Skill1HPiercing] = gmtrain->skills[EQEmu::skills::Skill2HPiercing];
|
||||
gmtrain->skills[EQEmu::skills::Skill2HPiercing] = 0;
|
||||
}
|
||||
//#pragma GCC pop_options
|
||||
|
||||
uchar ending[]={0x34,0x87,0x8a,0x3F,0x01
|
||||
@@ -1645,7 +1531,7 @@ void Client::OPGMTraining(const EQApplicationPacket *app)
|
||||
|
||||
void Client::OPGMEndTraining(const EQApplicationPacket *app)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GMEndTrainingResponse, 0);
|
||||
auto outapp = new EQApplicationPacket(OP_GMEndTrainingResponse, 0);
|
||||
GMTrainEnd_Struct *p = (GMTrainEnd_Struct *)app->pBuffer;
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
@@ -1710,14 +1596,14 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
else if (gmskill->skillbank == 0x00)
|
||||
{
|
||||
// normal skills go here
|
||||
if (gmskill->skill_id > HIGHEST_SKILL)
|
||||
if (gmskill->skill_id > EQEmu::skills::HIGHEST_SKILL)
|
||||
{
|
||||
std::cout << "Wrong Training Skill (abilities)" << std::endl;
|
||||
DumpPacket(app);
|
||||
return;
|
||||
}
|
||||
|
||||
SkillUseTypes skill = (SkillUseTypes) gmskill->skill_id;
|
||||
EQEmu::skills::SkillType skill = (EQEmu::skills::SkillType)gmskill->skill_id;
|
||||
|
||||
if(!CanHaveSkill(skill)) {
|
||||
Log.Out(Logs::Detail, Logs::Skills, "Tried to train skill %d, which is not allowed.", skill);
|
||||
@@ -1742,27 +1628,27 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
SetSkill(skill, t_level);
|
||||
} else {
|
||||
switch(skill) {
|
||||
case SkillBrewing:
|
||||
case SkillMakePoison:
|
||||
case SkillTinkering:
|
||||
case SkillResearch:
|
||||
case SkillAlchemy:
|
||||
case SkillBaking:
|
||||
case SkillTailoring:
|
||||
case SkillBlacksmithing:
|
||||
case SkillFletching:
|
||||
case SkillJewelryMaking:
|
||||
case SkillPottery:
|
||||
case EQEmu::skills::SkillBrewing:
|
||||
case EQEmu::skills::SkillMakePoison:
|
||||
case EQEmu::skills::SkillTinkering:
|
||||
case EQEmu::skills::SkillResearch:
|
||||
case EQEmu::skills::SkillAlchemy:
|
||||
case EQEmu::skills::SkillBaking:
|
||||
case EQEmu::skills::SkillTailoring:
|
||||
case EQEmu::skills::SkillBlacksmithing:
|
||||
case EQEmu::skills::SkillFletching:
|
||||
case EQEmu::skills::SkillJewelryMaking:
|
||||
case EQEmu::skills::SkillPottery:
|
||||
if(skilllevel >= RuleI(Skills, MaxTrainTradeskills)) {
|
||||
Message_StringID(13, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SkillSpecializeAbjure:
|
||||
case SkillSpecializeAlteration:
|
||||
case SkillSpecializeConjuration:
|
||||
case SkillSpecializeDivination:
|
||||
case SkillSpecializeEvocation:
|
||||
case EQEmu::skills::SkillSpecializeAbjure:
|
||||
case EQEmu::skills::SkillSpecializeAlteration:
|
||||
case EQEmu::skills::SkillSpecializeConjuration:
|
||||
case EQEmu::skills::SkillSpecializeDivination:
|
||||
case EQEmu::skills::SkillSpecializeEvocation:
|
||||
if(skilllevel >= RuleI(Skills, MaxTrainSpecializations)) {
|
||||
Message_StringID(13, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
||||
return;
|
||||
@@ -1779,7 +1665,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
if(gmskill->skill_id >= SkillSpecializeAbjure && gmskill->skill_id <= SkillSpecializeEvocation)
|
||||
if (gmskill->skill_id >= EQEmu::skills::SkillSpecializeAbjure && gmskill->skill_id <= EQEmu::skills::SkillSpecializeEvocation)
|
||||
{
|
||||
int MaxSpecSkill = GetMaxSkillAfterSpecializationRules(skill, MaxSkillValue);
|
||||
if (skilllevel >= MaxSpecSkill)
|
||||
@@ -1803,11 +1689,11 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
|
||||
if(GetClientVersion() >= ClientVersion::SoF) {
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
// The following packet decreases the skill points left in the Training Window and
|
||||
// produces the 'You have increased your skill / learned the basics of' message.
|
||||
//
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GMTrainSkillConfirm, sizeof(GMTrainSkillConfirm_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GMTrainSkillConfirm, sizeof(GMTrainSkillConfirm_Struct));
|
||||
|
||||
GMTrainSkillConfirm_Struct *gmtsc = (GMTrainSkillConfirm_Struct *)outapp->pBuffer;
|
||||
gmtsc->SkillID = gmskill->skill_id;
|
||||
@@ -1817,7 +1703,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
||||
gmtsc->SkillID += 100;
|
||||
}
|
||||
else
|
||||
gmtsc->NewSkill = (GetRawSkill((SkillUseTypes)gmtsc->SkillID) == 1);
|
||||
gmtsc->NewSkill = (GetRawSkill((EQEmu::skills::SkillType)gmtsc->SkillID) == 1);
|
||||
|
||||
gmtsc->Cost = Cost;
|
||||
|
||||
@@ -1865,7 +1751,7 @@ void Client::OPGMSummon(const EQApplicationPacket *app)
|
||||
}
|
||||
else if (tmp < '0' || tmp > '9') // dont send to world if it's not a player's name
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct));
|
||||
ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) pack->pBuffer;
|
||||
strcpy(szp->adminname, this->GetName());
|
||||
szp->adminrank = this->Admin();
|
||||
@@ -1907,7 +1793,7 @@ void Client::DoStaminaUpdate() {
|
||||
if(!stamina_timer.Check())
|
||||
return;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Stamina, sizeof(Stamina_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_Stamina, sizeof(Stamina_Struct));
|
||||
Stamina_Struct* sta = (Stamina_Struct*)outapp->pBuffer;
|
||||
|
||||
if(zone->GetZoneID() != 151) {
|
||||
@@ -2133,7 +2019,8 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
m_Position.z = corpse->GetZ();
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10);
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + 10);
|
||||
ZonePlayerToBind_Struct* gmg = (ZonePlayerToBind_Struct*) outapp->pBuffer;
|
||||
|
||||
gmg->bind_zone_id = zone->GetZoneID();
|
||||
@@ -2165,7 +2052,8 @@ void Client::HandleRespawnFromHover(uint32 Option)
|
||||
{
|
||||
PendingRezzSpellID = 0;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + chosen->name.length() + 1);
|
||||
auto outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) +
|
||||
chosen->name.length() + 1);
|
||||
ZonePlayerToBind_Struct* gmg = (ZonePlayerToBind_Struct*) outapp->pBuffer;
|
||||
|
||||
gmg->bind_zone_id = zone->GetZoneID();
|
||||
@@ -2232,7 +2120,7 @@ void Client::ClearHover()
|
||||
// Our Entity ID is currently zero, set in Client::Death
|
||||
SetID(entity_list.GetFreeID());
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ZoneEntry, sizeof(ServerZoneEntry_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_ZoneEntry, sizeof(ServerZoneEntry_Struct));
|
||||
ServerZoneEntry_Struct* sze = (ServerZoneEntry_Struct*)outapp->pBuffer;
|
||||
|
||||
FillSpawnStruct(&sze->player,CastToMob());
|
||||
@@ -2243,7 +2131,7 @@ void Client::ClearHover()
|
||||
entity_list.QueueClients(this, outapp, false);
|
||||
safe_delete(outapp);
|
||||
|
||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater)
|
||||
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::bit_UFAndLater)
|
||||
{
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
||||
CastToClient()->FastQueuePacket(&outapp);
|
||||
@@ -2284,7 +2172,7 @@ void Client::HandleLFGuildResponse(ServerPacket *pack)
|
||||
--i;
|
||||
}
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LFGuild, PacketSize);
|
||||
auto outapp = new EQApplicationPacket(OP_LFGuild, PacketSize);
|
||||
outapp->WriteUInt32(3);
|
||||
outapp->WriteUInt32(0xeb63); // Don't know the significance of this value.
|
||||
outapp->WriteUInt32(NumberOfMatches);
|
||||
@@ -2312,7 +2200,7 @@ void Client::HandleLFGuildResponse(ServerPacket *pack)
|
||||
}
|
||||
case QSG_LFGuild_RequestPlayerInfo:
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_PlayerToggle_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_PlayerToggle_Struct));
|
||||
LFGuild_PlayerToggle_Struct *pts = (LFGuild_PlayerToggle_Struct *)outapp->pBuffer;
|
||||
|
||||
pts->Command = 0;
|
||||
@@ -2342,7 +2230,7 @@ void Client::HandleLFGuildResponse(ServerPacket *pack)
|
||||
--i;
|
||||
}
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LFGuild, PacketSize);
|
||||
auto outapp = new EQApplicationPacket(OP_LFGuild, PacketSize);
|
||||
outapp->WriteUInt32(4);
|
||||
outapp->WriteUInt32(0xeb63);
|
||||
outapp->WriteUInt32(NumberOfMatches);
|
||||
@@ -2376,7 +2264,7 @@ void Client::HandleLFGuildResponse(ServerPacket *pack)
|
||||
TimeZone = pack->ReadUInt32();
|
||||
TimePosted = pack->ReadUInt32();
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_GuildToggle_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_GuildToggle_Struct));
|
||||
|
||||
LFGuild_GuildToggle_Struct *gts = (LFGuild_GuildToggle_Struct *)outapp->pBuffer;
|
||||
gts->Command = 1;
|
||||
@@ -2403,7 +2291,7 @@ void Client::HandleLFGuildResponse(ServerPacket *pack)
|
||||
|
||||
void Client::SendLFGuildStatus()
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(GetName()) + 17);
|
||||
auto pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(GetName()) + 17);
|
||||
|
||||
pack->WriteUInt32(zone->GetZoneID());
|
||||
pack->WriteUInt32(zone->GetInstanceID());
|
||||
@@ -2418,7 +2306,8 @@ void Client::SendLFGuildStatus()
|
||||
|
||||
void Client::SendGuildLFGuildStatus()
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_QueryServGeneric, strlen(GetName()) + +strlen(guild_mgr.GetGuildName(GuildID())) + 18);
|
||||
auto pack = new ServerPacket(ServerOP_QueryServGeneric,
|
||||
strlen(GetName()) + +strlen(guild_mgr.GetGuildName(GuildID())) + 18);
|
||||
|
||||
pack->WriteUInt32(zone->GetZoneID());
|
||||
pack->WriteUInt32(zone->GetInstanceID());
|
||||
|
||||
+711
-492
File diff suppressed because it is too large
Load Diff
+272
-276
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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
|
||||
@@ -25,315 +25,312 @@ class Seperator;
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
#define COMMAND_CHAR '#'
|
||||
#define CMDALIASES 5
|
||||
#define COMMAND_CHAR '#'
|
||||
|
||||
typedef void (*CmdFuncPtr)(Client *,const Seperator *);
|
||||
|
||||
// this is a command list item
|
||||
/*struct cl_struct
|
||||
{
|
||||
char *command[CMDALIASES]; // the command(s)
|
||||
char *desc; // description of command
|
||||
CmdFuncPtr function; // the function to call
|
||||
int access; // the required 'status' level
|
||||
|
||||
struct cl_struct *next; // linked list
|
||||
};
|
||||
|
||||
extern struct cl_struct *commandlist; // the head of the list
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char *command[CMDALIASES]; // the command(s)
|
||||
int access;
|
||||
const char *desc; // description of command
|
||||
CmdFuncPtr function; //null means perl function
|
||||
const char *desc; // description of command
|
||||
CmdFuncPtr function; // null means perl function
|
||||
} CommandRecord;
|
||||
|
||||
extern int (*command_dispatch)(Client *,char const*);
|
||||
extern int commandcount; // number of commands loaded
|
||||
extern int commandcount; // number of commands loaded
|
||||
|
||||
// the command system:
|
||||
int command_init(void);
|
||||
void command_deinit(void);
|
||||
int command_add(const char *command_string, const char *desc, int access, CmdFuncPtr function);
|
||||
int command_add(std::string command_name, const char *desc, int access, CmdFuncPtr function);
|
||||
int command_notavail(Client *c, const char *message);
|
||||
int command_realdispatch(Client *c, char const *message);
|
||||
void command_logcommand(Client *c, const char *message);
|
||||
|
||||
//commands
|
||||
void command_resetaa(Client* c,const Seperator *sep);
|
||||
void command_bind(Client* c,const Seperator *sep);
|
||||
void command_sendop(Client *c, const Seperator *sep);
|
||||
void command_optest(Client *c, const Seperator *sep);
|
||||
void command_setstat(Client *c, const Seperator *sep);
|
||||
void command_incstat(Client *c, const Seperator *sep);
|
||||
void command_help(Client *c, const Seperator *sep);
|
||||
void command_version(Client *c, const Seperator *sep);
|
||||
void command_setfaction(Client *c, const Seperator *sep);
|
||||
void command_serversidename(Client *c, const Seperator *sep);
|
||||
void command_testspawnkill(Client *c, const Seperator *sep);
|
||||
void command_testspawn(Client *c, const Seperator *sep);
|
||||
void command_wc(Client *c, const Seperator *sep);
|
||||
void command_heromodel(Client *c, const Seperator *sep);
|
||||
void command_numauths(Client *c, const Seperator *sep);
|
||||
void command_setanim(Client *c, const Seperator *sep);
|
||||
void command_connectworldserver(Client *c, const Seperator *sep);
|
||||
void command_serverinfo(Client *c, const Seperator *sep);
|
||||
void command_crashtest(Client *c, const Seperator *sep);
|
||||
void command_getvariable(Client *c, const Seperator *sep);
|
||||
void command_chat(Client *c, const Seperator *sep);
|
||||
void command_showpetspell(Client *c, const Seperator *sep);
|
||||
void command_ipc(Client *c, const Seperator *sep);
|
||||
void command_npcloot(Client *c, const Seperator *sep);
|
||||
void command_gm(Client *c, const Seperator *sep);
|
||||
void command_summon(Client *c, const Seperator *sep);
|
||||
void command_zone(Client *c, const Seperator *sep);
|
||||
void command_zone_instance(Client *c, const Seperator *sep);
|
||||
void command_peqzone(Client *c, const Seperator *sep);
|
||||
void command_showbuffs(Client *c, const Seperator *sep);
|
||||
void command_movechar(Client *c, const Seperator *sep);
|
||||
void command_viewpetition(Client *c, const Seperator *sep);
|
||||
void command_petitioninfo(Client *c, const Seperator *sep);
|
||||
void command_delpetition(Client *c, const Seperator *sep);
|
||||
void command_listnpcs(Client *c, const Seperator *sep);
|
||||
void command_date(Client *c, const Seperator *sep);
|
||||
void command_timezone(Client *c, const Seperator *sep);
|
||||
void command_synctod(Client *c, const Seperator *sep);
|
||||
void command_invul(Client *c, const Seperator *sep);
|
||||
void command_hideme(Client *c, const Seperator *sep);
|
||||
void command_emote(Client *c, const Seperator *sep);
|
||||
void command_fov(Client *c, const Seperator *sep);
|
||||
void command_manastat(Client *c, const Seperator *sep);
|
||||
void command_npcstats(Client *c, const Seperator *sep);
|
||||
void command_zclip(Client *c, const Seperator *sep);
|
||||
void command_npccast(Client *c, const Seperator *sep);
|
||||
void command_zstats(Client *c, const Seperator *sep);
|
||||
void command_permaclass(Client *c, const Seperator *sep);
|
||||
void command_permarace(Client *c, const Seperator *sep);
|
||||
void command_permagender(Client *c, const Seperator *sep);
|
||||
void command_weather(Client *c, const Seperator *sep);
|
||||
void command_zheader(Client *c, const Seperator *sep);
|
||||
void command_zsky(Client *c, const Seperator *sep);
|
||||
void command_zcolor(Client *c, const Seperator *sep);
|
||||
void command_spon(Client *c, const Seperator *sep);
|
||||
void command_spoff(Client *c, const Seperator *sep);
|
||||
void command_itemtest(Client *c, const Seperator *sep);
|
||||
void command_gassign(Client *c, const Seperator *sep);
|
||||
void command_acceptrules(Client *c, const Seperator *sep);
|
||||
void command_advnpcspawn(Client *c, const Seperator *sep);
|
||||
void command_aggro(Client *c, const Seperator *sep);
|
||||
void command_aggrozone(Client *c, const Seperator *sep);
|
||||
void command_ai(Client *c, const Seperator *sep);
|
||||
void command_worldshutdown(Client *c, const Seperator *sep);
|
||||
void command_sendzonespawns(Client *c, const Seperator *sep);
|
||||
void command_zsave(Client *c, const Seperator *sep);
|
||||
void command_dbspawn2(Client *c, const Seperator *sep);
|
||||
void command_shutdown(Client *c, const Seperator *sep);
|
||||
void command_delacct(Client *c, const Seperator *sep);
|
||||
void command_setpass(Client *c, const Seperator *sep);
|
||||
void command_setlsinfo(Client *c, const Seperator *sep);
|
||||
void command_grid(Client *c, const Seperator *sep);
|
||||
void command_wp(Client *c, const Seperator *sep);
|
||||
void command_iplookup(Client *c, const Seperator *sep);
|
||||
void command_size(Client *c, const Seperator *sep);
|
||||
void command_mana(Client *c, const Seperator *sep);
|
||||
void command_flymode(Client *c, const Seperator *sep);
|
||||
void command_showskills(Client *c, const Seperator *sep);
|
||||
void command_findspell(Client *c, const Seperator *sep);
|
||||
void command_castspell(Client *c, const Seperator *sep);
|
||||
void command_setlanguage(Client *c, const Seperator *sep);
|
||||
void command_setskill(Client *c, const Seperator *sep);
|
||||
void command_setskillall(Client *c, const Seperator *sep);
|
||||
void command_race(Client *c, const Seperator *sep);
|
||||
void command_gender(Client *c, const Seperator *sep);
|
||||
void command_makepet(Client *c, const Seperator *sep);
|
||||
void command_level(Client *c, const Seperator *sep);
|
||||
void command_spawn(Client *c, const Seperator *sep);
|
||||
void command_texture(Client *c, const Seperator *sep);
|
||||
void command_npctypespawn(Client *c, const Seperator *sep);
|
||||
void command_heal(Client *c, const Seperator *sep);
|
||||
void command_appearance(Client *c, const Seperator *sep);
|
||||
void command_nukeitem(Client *c, const Seperator *sep);
|
||||
void command_peekinv(Client *c, const Seperator *sep);
|
||||
void command_interrogateinv(Client *c, const Seperator *sep);
|
||||
void command_findnpctype(Client *c, const Seperator *sep);
|
||||
void command_findzone(Client *c, const Seperator *sep);
|
||||
void command_viewnpctype(Client *c, const Seperator *sep);
|
||||
void command_reloadqst(Client *c, const Seperator *sep);
|
||||
void command_reloadworld(Client *c, const Seperator *sep);
|
||||
void command_reloadzps(Client *c, const Seperator *sep);
|
||||
void command_zoneshutdown(Client *c, const Seperator *sep);
|
||||
void command_zonebootup(Client *c, const Seperator *sep);
|
||||
void command_kick(Client *c, const Seperator *sep);
|
||||
void command_apply_shared_memory(Client *c, const Seperator *sep);
|
||||
void command_attack(Client *c, const Seperator *sep);
|
||||
void command_lock(Client *c, const Seperator *sep);
|
||||
void command_unlock(Client *c, const Seperator *sep);
|
||||
void command_motd(Client *c, const Seperator *sep);
|
||||
void command_listpetition(Client *c, const Seperator *sep);
|
||||
void command_equipitem(Client *c, const Seperator *sep);
|
||||
void command_zonelock(Client *c, const Seperator *sep);
|
||||
void command_corpse(Client *c, const Seperator *sep);
|
||||
void command_fixmob(Client *c, const Seperator *sep);
|
||||
void command_gmspeed(Client *c, const Seperator *sep);
|
||||
void command_title(Client *c, const Seperator *sep);
|
||||
void command_titlesuffix(Client *c, const Seperator *sep);
|
||||
void command_spellinfo(Client *c, const Seperator *sep);
|
||||
void command_lastname(Client *c, const Seperator *sep);
|
||||
void command_memspell(Client *c, const Seperator *sep);
|
||||
void command_save(Client *c, const Seperator *sep);
|
||||
void command_showstats(Client *c, const Seperator *sep);
|
||||
void command_mystats(Client *c, const Seperator *sep);
|
||||
void command_myskills(Client *c, const Seperator *sep);
|
||||
void command_depop(Client *c, const Seperator *sep);
|
||||
void command_depopzone(Client *c, const Seperator *sep);
|
||||
void command_repop(Client *c, const Seperator *sep);
|
||||
void command_spawnstatus(Client *c, const Seperator *sep);
|
||||
void command_nukebuffs(Client *c, const Seperator *sep);
|
||||
void command_zuwcoords(Client *c, const Seperator *sep);
|
||||
void command_zunderworld(Client *c, const Seperator *sep);
|
||||
void command_zsafecoords(Client *c, const Seperator *sep);
|
||||
void command_freeze(Client *c, const Seperator *sep);
|
||||
void command_unfreeze(Client *c, const Seperator *sep);
|
||||
void command_pvp(Client *c, const Seperator *sep);
|
||||
void command_setxp(Client *c, const Seperator *sep);
|
||||
void command_setpvppoints(Client *c, const Seperator *sep);
|
||||
void command_name(Client *c, const Seperator *sep);
|
||||
void command_tempname(Client *c, const Seperator *sep);
|
||||
void command_npcspecialattk(Client *c, const Seperator *sep);
|
||||
void command_kill(Client *c, const Seperator *sep);
|
||||
void command_haste(Client *c, const Seperator *sep);
|
||||
void command_damage(Client *c, const Seperator *sep);
|
||||
void command_zonespawn(Client *c, const Seperator *sep);
|
||||
void command_npcspawn(Client *c, const Seperator *sep);
|
||||
void command_spawnfix(Client *c, const Seperator *sep);
|
||||
void command_loc(Client *c, const Seperator *sep);
|
||||
void command_goto(Client *c, const Seperator *sep);
|
||||
void command_augmentitem(Client *c, const Seperator *sep);
|
||||
void command_ban(Client *c, const Seperator *sep);
|
||||
void command_beard(Client *c, const Seperator *sep);
|
||||
void command_beardcolor(Client *c, const Seperator *sep);
|
||||
void command_bind(Client* c, const Seperator *sep);
|
||||
|
||||
#ifdef BUGTRACK
|
||||
void command_bug(Client *c, const Seperator *sep);
|
||||
#endif
|
||||
void command_iteminfo(Client *c, const Seperator *sep);
|
||||
void command_uptime(Client *c, const Seperator *sep);
|
||||
void command_flag(Client *c, const Seperator *sep);
|
||||
void command_time(Client *c, const Seperator *sep);
|
||||
void command_guild(Client *c, const Seperator *sep);
|
||||
bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char* what, const char* value);
|
||||
void command_zonestatus(Client *c, const Seperator *sep);
|
||||
void command_manaburn(Client *c, const Seperator *sep);
|
||||
void command_doanim(Client *c, const Seperator *sep);
|
||||
void command_randomfeatures(Client *c, const Seperator *sep);
|
||||
void command_face(Client *c, const Seperator *sep);
|
||||
void command_helm(Client *c, const Seperator *sep);
|
||||
void command_hair(Client *c, const Seperator *sep);
|
||||
void command_haircolor(Client *c, const Seperator *sep);
|
||||
void command_beard(Client *c, const Seperator *sep);
|
||||
void command_beardcolor(Client *c, const Seperator *sep);
|
||||
void command_tattoo(Client *c, const Seperator *sep);
|
||||
void command_heritage(Client *c, const Seperator *sep);
|
||||
void command_details(Client *c, const Seperator *sep);
|
||||
void command_scribespells(Client *c, const Seperator *sep);
|
||||
void command_unscribespells(Client *c, const Seperator *sep);
|
||||
void command_wpinfo(Client *c, const Seperator *sep);
|
||||
void command_wpadd(Client *c, const Seperator *sep);
|
||||
void command_interrupt(Client *c, const Seperator *sep);
|
||||
|
||||
void command_camerashake(Client *c, const Seperator *sep);
|
||||
void command_castspell(Client *c, const Seperator *sep);
|
||||
void command_chat(Client *c, const Seperator *sep);
|
||||
void command_checklos(Client *c, const Seperator *sep);
|
||||
void command_clearinvsnapshots(Client *c, const Seperator *sep);
|
||||
void command_connectworldserver(Client *c, const Seperator *sep);
|
||||
void command_corpse(Client *c, const Seperator *sep);
|
||||
void command_crashtest(Client *c, const Seperator *sep);
|
||||
void command_cvs(Client *c, const Seperator *sep);
|
||||
void command_d1(Client *c, const Seperator *sep);
|
||||
void command_summonitem(Client *c, const Seperator *sep);
|
||||
void command_damage(Client *c, const Seperator *sep);
|
||||
void command_date(Client *c, const Seperator *sep);
|
||||
void command_dbspawn2(Client *c, const Seperator *sep);
|
||||
void command_delacct(Client *c, const Seperator *sep);
|
||||
void command_deletegraveyard(Client *c, const Seperator *sep);
|
||||
void command_delpetition(Client *c, const Seperator *sep);
|
||||
void command_depop(Client *c, const Seperator *sep);
|
||||
void command_depopzone(Client *c, const Seperator *sep);
|
||||
void command_details(Client *c, const Seperator *sep);
|
||||
void command_disablerecipe(Client *c, const Seperator *sep);
|
||||
void command_disarmtrap(Client *c, const Seperator *sep);
|
||||
void command_distance(Client *c, const Seperator *sep);
|
||||
void command_doanim(Client *c, const Seperator *sep);
|
||||
void command_emote(Client *c, const Seperator *sep);
|
||||
void command_emotesearch(Client* c, const Seperator *sep);
|
||||
void command_emoteview(Client* c, const Seperator *sep);
|
||||
void command_enablerecipe(Client *c, const Seperator *sep);
|
||||
void command_equipitem(Client *c, const Seperator *sep);
|
||||
void command_face(Client *c, const Seperator *sep);
|
||||
void command_findaliases(Client *c, const Seperator *sep);
|
||||
void command_findnpctype(Client *c, const Seperator *sep);
|
||||
void command_findspell(Client *c, const Seperator *sep);
|
||||
void command_findzone(Client *c, const Seperator *sep);
|
||||
void command_fixmob(Client *c, const Seperator *sep);
|
||||
void command_flag(Client *c, const Seperator *sep);
|
||||
void command_flagedit(Client *c, const Seperator *sep);
|
||||
void command_flags(Client *c, const Seperator *sep);
|
||||
void command_flymode(Client *c, const Seperator *sep);
|
||||
void command_fov(Client *c, const Seperator *sep);
|
||||
void command_freeze(Client *c, const Seperator *sep);
|
||||
void command_gassign(Client *c, const Seperator *sep);
|
||||
void command_gender(Client *c, const Seperator *sep);
|
||||
void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep);
|
||||
void command_getvariable(Client *c, const Seperator *sep);
|
||||
void command_ginfo(Client *c, const Seperator *sep);
|
||||
void command_giveitem(Client *c, const Seperator *sep);
|
||||
void command_givemoney(Client *c, const Seperator *sep);
|
||||
void command_itemsearch(Client *c, const Seperator *sep);
|
||||
void command_setaaxp(Client *c, const Seperator *sep);
|
||||
void command_setaapts(Client *c, const Seperator *sep);
|
||||
void command_setcrystals(Client *c, const Seperator *sep);
|
||||
void command_stun(Client *c, const Seperator *sep);
|
||||
void command_ban(Client *c, const Seperator *sep);
|
||||
void command_suspend(Client *c, const Seperator *sep);
|
||||
void command_globalview(Client* c, const Seperator *sep);
|
||||
void command_gm(Client *c, const Seperator *sep);
|
||||
void command_gmspeed(Client *c, const Seperator *sep);
|
||||
void command_goto(Client *c, const Seperator *sep);
|
||||
void command_grid(Client *c, const Seperator *sep);
|
||||
void command_guild(Client *c, const Seperator *sep);
|
||||
bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char* what, const char* value);
|
||||
void command_guildapprove(Client *c, const Seperator *sep);
|
||||
void command_guildcreate(Client *c, const Seperator *sep);
|
||||
void command_guildlist(Client *c, const Seperator *sep);
|
||||
void command_hair(Client *c, const Seperator *sep);
|
||||
void command_haircolor(Client *c, const Seperator *sep);
|
||||
void command_haste(Client *c, const Seperator *sep);
|
||||
void command_hatelist(Client *c, const Seperator *sep);
|
||||
void command_heal(Client *c, const Seperator *sep);
|
||||
void command_helm(Client *c, const Seperator *sep);
|
||||
void command_help(Client *c, const Seperator *sep);
|
||||
void command_heritage(Client *c, const Seperator *sep);
|
||||
void command_heromodel(Client *c, const Seperator *sep);
|
||||
void command_hideme(Client *c, const Seperator *sep);
|
||||
void command_hotfix(Client *c, const Seperator *sep);
|
||||
void command_hp(Client *c, const Seperator *sep);
|
||||
void command_incstat(Client *c, const Seperator *sep);
|
||||
void command_instance(Client *c, const Seperator *sep);
|
||||
void command_interrogateinv(Client *c, const Seperator *sep);
|
||||
void command_interrupt(Client *c, const Seperator *sep);
|
||||
void command_invsnapshot(Client *c, const Seperator *sep);
|
||||
void command_invul(Client *c, const Seperator *sep);
|
||||
void command_ipban(Client *c, const Seperator *sep);
|
||||
void command_oocmute(Client *c, const Seperator *sep);
|
||||
void command_revoke(Client *c, const Seperator *sep);
|
||||
void command_checklos(Client *c, const Seperator *sep);
|
||||
void command_set_adventure_points(Client *c, const Seperator *sep);
|
||||
void command_ipc(Client *c, const Seperator *sep);
|
||||
void command_iplookup(Client *c, const Seperator *sep);
|
||||
void command_iteminfo(Client *c, const Seperator *sep);
|
||||
void command_itemsearch(Client *c, const Seperator *sep);
|
||||
void command_itemtest(Client *c, const Seperator *sep);
|
||||
void command_kick(Client *c, const Seperator *sep);
|
||||
void command_kill(Client *c, const Seperator *sep);
|
||||
void command_lastname(Client *c, const Seperator *sep);
|
||||
void command_level(Client *c, const Seperator *sep);
|
||||
void command_listnpcs(Client *c, const Seperator *sep);
|
||||
void command_listpetition(Client *c, const Seperator *sep);
|
||||
void command_load_shared_memory(Client *c, const Seperator *sep);
|
||||
void command_loc(Client *c, const Seperator *sep);
|
||||
void command_lock(Client *c, const Seperator *sep);
|
||||
void command_logs(Client *c, const Seperator *sep);
|
||||
void command_logtest(Client *c, const Seperator *sep);
|
||||
void command_makepet(Client *c, const Seperator *sep);
|
||||
void command_mana(Client *c, const Seperator *sep);
|
||||
void command_manastat(Client *c, const Seperator *sep);
|
||||
void command_max_all_skills(Client *c, const Seperator *sep);
|
||||
void command_memspell(Client *c, const Seperator *sep);
|
||||
void command_merchantcloseshop(Client *c, const Seperator *sep);
|
||||
void command_merchantopenshop(Client *c, const Seperator *sep);
|
||||
void command_modifynpcstat(Client *c, const Seperator *sep);
|
||||
void command_motd(Client *c, const Seperator *sep);
|
||||
void command_movechar(Client *c, const Seperator *sep);
|
||||
void command_myskills(Client *c, const Seperator *sep);
|
||||
void command_mysql(Client *c, const Seperator *sep);
|
||||
void command_mysqltest(Client *c, const Seperator *sep);
|
||||
void command_mystats(Client *c, const Seperator *sep);
|
||||
void command_name(Client *c, const Seperator *sep);
|
||||
void command_netstats(Client *c, const Seperator *sep);
|
||||
void command_npccast(Client *c, const Seperator *sep);
|
||||
void command_npcedit(Client *c, const Seperator *sep);
|
||||
void command_npcemote(Client *c, const Seperator *sep);
|
||||
void command_npcloot(Client *c, const Seperator *sep);
|
||||
void command_npcsay(Client *c, const Seperator *sep);
|
||||
void command_npcshout(Client *c, const Seperator *sep);
|
||||
void command_npcemote(Client *c, const Seperator *sep);
|
||||
void command_npcedit(Client *c, const Seperator *sep);
|
||||
void command_timers(Client *c, const Seperator *sep);
|
||||
void command_undye(Client *c, const Seperator *sep);
|
||||
void command_undyeme(Client *c, const Seperator *sep);
|
||||
void command_hp(Client *c, const Seperator *sep);
|
||||
void command_ginfo(Client *c, const Seperator *sep);
|
||||
void command_qglobal(Client *c, const Seperator *sep);
|
||||
void command_path(Client *c, const Seperator *sep);
|
||||
void command_ginfo(Client *c, const Seperator *sep);
|
||||
void command_opcode(Client *c, const Seperator *sep);
|
||||
void command_aggro(Client *c, const Seperator *sep);
|
||||
void command_hatelist(Client *c, const Seperator *sep);
|
||||
void command_aggrozone(Client *c, const Seperator *sep);
|
||||
void command_reloadstatic(Client *c, const Seperator *sep);
|
||||
void command_flags(Client *c, const Seperator *sep);
|
||||
void command_flagedit(Client *c, const Seperator *sep);
|
||||
void command_serverrules(Client *c, const Seperator *sep);
|
||||
void command_acceptrules(Client *c, const Seperator *sep);
|
||||
void command_guildcreate(Client *c, const Seperator *sep);
|
||||
void command_guildapprove(Client *c, const Seperator *sep);
|
||||
void command_guildlist(Client *c, const Seperator *sep);
|
||||
void command_rules(Client *c, const Seperator *sep);
|
||||
void command_task(Client *c, const Seperator *sep);
|
||||
void command_reloadtitles(Client *c, const Seperator *sep);
|
||||
void command_altactivate(Client *c, const Seperator *sep);
|
||||
void command_refundaa(Client *c, const Seperator *sep);
|
||||
void command_traindisc(Client *c, const Seperator *sep);
|
||||
void command_deletegraveyard(Client *c, const Seperator *sep);
|
||||
void command_setgraveyard(Client *c, const Seperator *sep);
|
||||
void command_getplayerburriedcorpsecount(Client *c, const Seperator *sep);
|
||||
void command_summonburriedplayercorpse(Client *c, const Seperator *sep);
|
||||
void command_unscribespell(Client *c, const Seperator *sep);
|
||||
void command_scribespell(Client *c, const Seperator *sep);
|
||||
void command_refreshgroup(Client *c, const Seperator *sep);
|
||||
void command_advnpcspawn(Client *c, const Seperator *sep);
|
||||
void command_modifynpcstat(Client *c, const Seperator *sep);
|
||||
void command_instance(Client *c, const Seperator *sep);
|
||||
void command_setstartzone(Client *c, const Seperator *sep);
|
||||
void command_netstats(Client *c, const Seperator *sep);
|
||||
void command_object(Client* c, const Seperator *sep);
|
||||
void command_raidloot(Client* c, const Seperator *sep);
|
||||
void command_globalview(Client* c, const Seperator *sep);
|
||||
void command_emoteview(Client* c, const Seperator *sep);
|
||||
void command_reloademote(Client* c, const Seperator *sep);
|
||||
void command_emotesearch(Client* c, const Seperator *sep);
|
||||
void command_distance(Client *c, const Seperator *sep);
|
||||
void command_cvs(Client *c, const Seperator *sep);
|
||||
void command_max_all_skills(Client *c, const Seperator *sep);
|
||||
void command_showbonusstats(Client *c, const Seperator *sep);
|
||||
void command_reloadallrules(Client *c, const Seperator *sep);
|
||||
void command_reloadworldrules(Client *c, const Seperator *sep);
|
||||
void command_reloadlevelmods(Client *c, const Seperator *sep);
|
||||
void command_camerashake(Client *c, const Seperator *sep);
|
||||
void command_disarmtrap(Client *c, const Seperator *sep);
|
||||
void command_sensetrap(Client *c, const Seperator *sep);
|
||||
void command_picklock(Client *c, const Seperator *sep);
|
||||
void command_qtest(Client *c, const Seperator *sep);
|
||||
void command_mysql(Client *c, const Seperator *sep);
|
||||
void command_xtargets(Client *c, const Seperator *sep);
|
||||
void command_zopp(Client *c, const Seperator *sep);
|
||||
void command_augmentitem(Client *c, const Seperator *sep);
|
||||
void command_questerrors(Client *c, const Seperator *sep);
|
||||
void command_enablerecipe(Client *c, const Seperator *sep);
|
||||
void command_disablerecipe(Client *c, const Seperator *sep);
|
||||
void command_showspellslist(Client *c, const Seperator *sep);
|
||||
void command_npcspawn(Client *c, const Seperator *sep);
|
||||
void command_npcspecialattk(Client *c, const Seperator *sep);
|
||||
void command_npcstats(Client *c, const Seperator *sep);
|
||||
void command_npctype_cache(Client *c, const Seperator *sep);
|
||||
void command_merchantopenshop(Client *c, const Seperator *sep);
|
||||
void command_merchantcloseshop(Client *c, const Seperator *sep);
|
||||
void command_shownumhits(Client *c, const Seperator *sep);
|
||||
void command_tune(Client *c, const Seperator *sep);
|
||||
void command_logtest(Client *c, const Seperator *sep);
|
||||
void command_mysqltest(Client *c, const Seperator *sep);
|
||||
void command_logs(Client *c, const Seperator *sep);
|
||||
|
||||
void command_npctypespawn(Client *c, const Seperator *sep);
|
||||
void command_nukebuffs(Client *c, const Seperator *sep);
|
||||
void command_nukeitem(Client *c, const Seperator *sep);
|
||||
void command_numauths(Client *c, const Seperator *sep);
|
||||
void command_object(Client* c, const Seperator *sep);
|
||||
void command_oocmute(Client *c, const Seperator *sep);
|
||||
void command_opcode(Client *c, const Seperator *sep);
|
||||
void command_optest(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef PACKET_PROFILER
|
||||
void command_packetprofile(Client *c, const Seperator *sep);
|
||||
#endif
|
||||
|
||||
void command_path(Client *c, const Seperator *sep);
|
||||
void command_peekinv(Client *c, const Seperator *sep);
|
||||
void command_peqzone(Client *c, const Seperator *sep);
|
||||
void command_permaclass(Client *c, const Seperator *sep);
|
||||
void command_permagender(Client *c, const Seperator *sep);
|
||||
void command_permarace(Client *c, const Seperator *sep);
|
||||
void command_petitioninfo(Client *c, const Seperator *sep);
|
||||
void command_picklock(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef EQPROFILE
|
||||
void command_profiledump(Client *c, const Seperator *sep);
|
||||
void command_profilereset(Client *c, const Seperator *sep);
|
||||
#endif
|
||||
|
||||
#ifdef PACKET_PROFILER
|
||||
void command_packetprofile(Client *c, const Seperator *sep);
|
||||
#endif
|
||||
void command_pvp(Client *c, const Seperator *sep);
|
||||
void command_qglobal(Client *c, const Seperator *sep);
|
||||
void command_qtest(Client *c, const Seperator *sep);
|
||||
void command_questerrors(Client *c, const Seperator *sep);
|
||||
void command_race(Client *c, const Seperator *sep);
|
||||
void command_raidloot(Client* c, const Seperator *sep);
|
||||
void command_randomfeatures(Client *c, const Seperator *sep);
|
||||
void command_refreshgroup(Client *c, const Seperator *sep);
|
||||
void command_refundaa(Client *c, const Seperator *sep);
|
||||
void command_reloadaa(Client *c, const Seperator *sep);
|
||||
void command_reloadallrules(Client *c, const Seperator *sep);
|
||||
void command_reloademote(Client* c, const Seperator *sep);
|
||||
void command_reloadlevelmods(Client *c, const Seperator *sep);
|
||||
void command_reloadperlexportsettings(Client *c, const Seperator *sep);
|
||||
void command_reloadqst(Client *c, const Seperator *sep);
|
||||
void command_reloadstatic(Client *c, const Seperator *sep);
|
||||
void command_reloadtitles(Client *c, const Seperator *sep);
|
||||
void command_reloadworld(Client *c, const Seperator *sep);
|
||||
void command_reloadworldrules(Client *c, const Seperator *sep);
|
||||
void command_reloadzps(Client *c, const Seperator *sep);
|
||||
void command_repop(Client *c, const Seperator *sep);
|
||||
void command_repopclose(Client *c, const Seperator *sep);
|
||||
void command_resetaa(Client* c,const Seperator *sep);
|
||||
void command_resetaa_timer(Client *c, const Seperator *sep);
|
||||
void command_revoke(Client *c, const Seperator *sep);
|
||||
void command_rules(Client *c, const Seperator *sep);
|
||||
void command_save(Client *c, const Seperator *sep);
|
||||
void command_scribespell(Client *c, const Seperator *sep);
|
||||
void command_scribespells(Client *c, const Seperator *sep);
|
||||
void command_sendop(Client *c, const Seperator *sep);
|
||||
void command_sendzonespawns(Client *c, const Seperator *sep);
|
||||
void command_sensetrap(Client *c, const Seperator *sep);
|
||||
void command_serverinfo(Client *c, const Seperator *sep);
|
||||
void command_serverrules(Client *c, const Seperator *sep);
|
||||
void command_serversidename(Client *c, const Seperator *sep);
|
||||
void command_set_adventure_points(Client *c, const Seperator *sep);
|
||||
void command_setaapts(Client *c, const Seperator *sep);
|
||||
void command_setaaxp(Client *c, const Seperator *sep);
|
||||
void command_setanim(Client *c, const Seperator *sep);
|
||||
void command_setcrystals(Client *c, const Seperator *sep);
|
||||
void command_setfaction(Client *c, const Seperator *sep);
|
||||
void command_setgraveyard(Client *c, const Seperator *sep);
|
||||
void command_setlanguage(Client *c, const Seperator *sep);
|
||||
void command_setlsinfo(Client *c, const Seperator *sep);
|
||||
void command_setpass(Client *c, const Seperator *sep);
|
||||
void command_setpvppoints(Client *c, const Seperator *sep);
|
||||
void command_setskill(Client *c, const Seperator *sep);
|
||||
void command_setskillall(Client *c, const Seperator *sep);
|
||||
void command_setstartzone(Client *c, const Seperator *sep);
|
||||
void command_setstat(Client *c, const Seperator *sep);
|
||||
void command_setxp(Client *c, const Seperator *sep);
|
||||
void command_showbonusstats(Client *c, const Seperator *sep);
|
||||
void command_showbuffs(Client *c, const Seperator *sep);
|
||||
void command_shownumhits(Client *c, const Seperator *sep);
|
||||
void command_showpetspell(Client *c, const Seperator *sep);
|
||||
void command_showskills(Client *c, const Seperator *sep);
|
||||
void command_showspellslist(Client *c, const Seperator *sep);
|
||||
void command_showstats(Client *c, const Seperator *sep);
|
||||
void command_shutdown(Client *c, const Seperator *sep);
|
||||
void command_size(Client *c, const Seperator *sep);
|
||||
void command_spawn(Client *c, const Seperator *sep);
|
||||
void command_spawnfix(Client *c, const Seperator *sep);
|
||||
void command_spawnstatus(Client *c, const Seperator *sep);
|
||||
void command_spellinfo(Client *c, const Seperator *sep);
|
||||
void command_spoff(Client *c, const Seperator *sep);
|
||||
void command_spon(Client *c, const Seperator *sep);
|
||||
void command_stun(Client *c, const Seperator *sep);
|
||||
void command_summon(Client *c, const Seperator *sep);
|
||||
void command_summonburiedplayercorpse(Client *c, const Seperator *sep);
|
||||
void command_summonitem(Client *c, const Seperator *sep);
|
||||
void command_suspend(Client *c, const Seperator *sep);
|
||||
void command_synctod(Client *c, const Seperator *sep);
|
||||
void command_task(Client *c, const Seperator *sep);
|
||||
void command_tattoo(Client *c, const Seperator *sep);
|
||||
void command_tempname(Client *c, const Seperator *sep);
|
||||
void command_testspawn(Client *c, const Seperator *sep);
|
||||
void command_testspawnkill(Client *c, const Seperator *sep);
|
||||
void command_texture(Client *c, const Seperator *sep);
|
||||
void command_time(Client *c, const Seperator *sep);
|
||||
void command_timers(Client *c, const Seperator *sep);
|
||||
void command_timezone(Client *c, const Seperator *sep);
|
||||
void command_title(Client *c, const Seperator *sep);
|
||||
void command_titlesuffix(Client *c, const Seperator *sep);
|
||||
void command_traindisc(Client *c, const Seperator *sep);
|
||||
void command_tune(Client *c, const Seperator *sep);
|
||||
void command_undye(Client *c, const Seperator *sep);
|
||||
void command_undyeme(Client *c, const Seperator *sep);
|
||||
void command_unfreeze(Client *c, const Seperator *sep);
|
||||
void command_unlock(Client *c, const Seperator *sep);
|
||||
void command_unscribespell(Client *c, const Seperator *sep);
|
||||
void command_unscribespells(Client *c, const Seperator *sep);
|
||||
void command_untraindisc(Client *c, const Seperator *sep);
|
||||
void command_untraindiscs(Client *c, const Seperator *sep);
|
||||
void command_uptime(Client *c, const Seperator *sep);
|
||||
void command_version(Client *c, const Seperator *sep);
|
||||
void command_viewnpctype(Client *c, const Seperator *sep);
|
||||
void command_viewpetition(Client *c, const Seperator *sep);
|
||||
void command_wc(Client *c, const Seperator *sep);
|
||||
void command_weather(Client *c, const Seperator *sep);
|
||||
void command_worldshutdown(Client *c, const Seperator *sep);
|
||||
void command_wp(Client *c, const Seperator *sep);
|
||||
void command_wpadd(Client *c, const Seperator *sep);
|
||||
void command_wpinfo(Client *c, const Seperator *sep);
|
||||
void command_xtargets(Client *c, const Seperator *sep);
|
||||
void command_zclip(Client *c, const Seperator *sep);
|
||||
void command_zcolor(Client *c, const Seperator *sep);
|
||||
void command_zheader(Client *c, const Seperator *sep);
|
||||
void command_zone(Client *c, const Seperator *sep);
|
||||
void command_zone_instance(Client *c, const Seperator *sep);
|
||||
void command_zonebootup(Client *c, const Seperator *sep);
|
||||
void command_zonelock(Client *c, const Seperator *sep);
|
||||
void command_zoneshutdown(Client *c, const Seperator *sep);
|
||||
void command_zonespawn(Client *c, const Seperator *sep);
|
||||
void command_zonestatus(Client *c, const Seperator *sep);
|
||||
void command_zopp(Client *c, const Seperator *sep);
|
||||
void command_zsafecoords(Client *c, const Seperator *sep);
|
||||
void command_zsave(Client *c, const Seperator *sep);
|
||||
void command_zsky(Client *c, const Seperator *sep);
|
||||
void command_zstats(Client *c, const Seperator *sep);
|
||||
void command_zunderworld(Client *c, const Seperator *sep);
|
||||
void command_zuwcoords(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef BOTS
|
||||
#include "bot.h"
|
||||
@@ -341,4 +338,3 @@ void command_bot(Client*c, const Seperator *sep);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+62
-27
@@ -17,12 +17,6 @@
|
||||
#define _NPCPET(x) (x && x->IsNPC() && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsNPC())
|
||||
#define _BECOMENPCPET(x) (x && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsClient() && x->CastToMob()->GetOwner()->CastToClient()->IsBecomeNPC())
|
||||
|
||||
#define USE_ITEM_SPELL_SLOT 10
|
||||
#define POTION_BELT_SPELL_SLOT 11
|
||||
#define TARGET_RING_SPELL_SLOT 12
|
||||
#define DISCIPLINE_SPELL_SLOT 10
|
||||
#define ABILITY_SPELL_SLOT 9
|
||||
|
||||
//LOS Parameters:
|
||||
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
|
||||
#define SEE_POSITION 0.5f //ratio of GetSize() where NPCs try to see for LOS
|
||||
@@ -61,6 +55,7 @@ typedef enum { //focus types
|
||||
focusManaCost,
|
||||
focusImprovedHeal,
|
||||
focusImprovedDamage,
|
||||
focusImprovedDamage2,
|
||||
focusImprovedDOT, //i dont know about this...
|
||||
focusFcDamagePctCrit,
|
||||
focusImprovedUndeadDamage,
|
||||
@@ -72,6 +67,7 @@ typedef enum { //focus types
|
||||
focusTwincast,
|
||||
focusSympatheticProc,
|
||||
focusFcDamageAmt,
|
||||
focusFcDamageAmt2,
|
||||
focusFcDamageAmtCrit,
|
||||
focusSpellDurByTic,
|
||||
focusSwarmPetDuration,
|
||||
@@ -137,7 +133,8 @@ enum {
|
||||
IGNORE_ROOT_AGGRO_RULES = 42,
|
||||
CASTING_RESIST_DIFF = 43,
|
||||
COUNTER_AVOID_DAMAGE = 44,
|
||||
MAX_SPECIAL_ATTACK = 45
|
||||
PROX_AGGRO = 45,
|
||||
MAX_SPECIAL_ATTACK = 46
|
||||
};
|
||||
|
||||
typedef enum { //fear states
|
||||
@@ -173,6 +170,28 @@ enum class NumHit { // Numhits type
|
||||
OffensiveSpellProcs = 11 // Offensive buff procs
|
||||
};
|
||||
|
||||
enum class PlayerState : uint32 {
|
||||
None = 0,
|
||||
Open = 1,
|
||||
WeaponSheathed = 2,
|
||||
Aggressive = 4,
|
||||
ForcedAggressive = 8,
|
||||
InstrumentEquipped = 16,
|
||||
Stunned = 32,
|
||||
PrimaryWeaponEquipped = 64,
|
||||
SecondaryWeaponEquipped = 128
|
||||
};
|
||||
|
||||
enum class LootResponse : uint8 {
|
||||
SomeoneElse = 0,
|
||||
Normal = 1,
|
||||
NotAtThisTime = 2,
|
||||
Normal2 = 3, // acts exactly the same as Normal, maybe group vs ungroup? No idea
|
||||
Hostiles = 4,
|
||||
TooFar = 5,
|
||||
LootAll = 6 // SoD+
|
||||
};
|
||||
|
||||
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
||||
struct Buffs_Struct {
|
||||
uint16 spellid;
|
||||
@@ -190,6 +209,7 @@ struct Buffs_Struct {
|
||||
int32 caston_z;
|
||||
int32 ExtraDIChance;
|
||||
int16 RootBreakChance; //Not saved to dbase
|
||||
uint32 instrument_mod;
|
||||
bool persistant_buff;
|
||||
bool client; //True if the caster is a client
|
||||
bool UpdateClient;
|
||||
@@ -260,7 +280,8 @@ struct StatBonuses {
|
||||
int32 inhibitmelee;
|
||||
float AggroRange; // when calculate just replace original value with this
|
||||
float AssistRange;
|
||||
int32 skillmod[HIGHEST_SKILL+1];
|
||||
int32 skillmod[EQEmu::skills::HIGHEST_SKILL + 1];
|
||||
int32 skillmodmax[EQEmu::skills::HIGHEST_SKILL + 1];
|
||||
int effective_casting_level;
|
||||
int reflect_chance; // chance to reflect incoming spell
|
||||
uint32 singingMod;
|
||||
@@ -276,7 +297,7 @@ struct StatBonuses {
|
||||
int32 StrikeThrough; // PoP: Strike Through %
|
||||
int32 MeleeMitigation; //i = Shielding
|
||||
int32 MeleeMitigationEffect; //i = Spell Effect Melee Mitigation
|
||||
int32 CriticalHitChance[HIGHEST_SKILL+2]; //i
|
||||
int32 CriticalHitChance[EQEmu::skills::HIGHEST_SKILL + 2]; //i
|
||||
int32 CriticalSpellChance; //i
|
||||
int32 SpellCritDmgIncrease; //i
|
||||
int32 SpellCritDmgIncNoStack; // increase
|
||||
@@ -303,10 +324,10 @@ struct StatBonuses {
|
||||
int32 MeleeSkillCheck; //i
|
||||
uint8 MeleeSkillCheckSkill;
|
||||
int32 HitChance; //HitChance/15 == % increase i = Accuracy (Item: Accuracy)
|
||||
int32 HitChanceEffect[HIGHEST_SKILL+2]; //Spell effect Chance to Hit, straight percent increase
|
||||
int32 DamageModifier[HIGHEST_SKILL+2]; //i
|
||||
int32 DamageModifier2[HIGHEST_SKILL+2]; //i
|
||||
int32 MinDamageModifier[HIGHEST_SKILL+2]; //i
|
||||
int32 HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 2]; //Spell effect Chance to Hit, straight percent increase
|
||||
int32 DamageModifier[EQEmu::skills::HIGHEST_SKILL + 2]; //i
|
||||
int32 DamageModifier2[EQEmu::skills::HIGHEST_SKILL + 2]; //i
|
||||
int32 MinDamageModifier[EQEmu::skills::HIGHEST_SKILL + 2]; //i
|
||||
int32 ProcChance; // ProcChance/10 == % increase i = CombatEffects
|
||||
int32 ProcChanceSPA; // ProcChance from spell effects
|
||||
int32 ExtraAttackChance;
|
||||
@@ -314,13 +335,13 @@ struct StatBonuses {
|
||||
int32 DivineSaveChance[2]; // Second Chance (base1 = chance, base2 = spell on trigger)
|
||||
uint32 DeathSave[4]; // Death Pact [0](value = 1 partial 2 = full) [1]=slot [2]=LvLimit [3]=HealAmt
|
||||
int32 FlurryChance;
|
||||
int32 Accuracy[HIGHEST_SKILL+2]; //Accuracy/15 == % increase [Spell Effect: Accuracy)
|
||||
int32 Accuracy[EQEmu::skills::HIGHEST_SKILL + 2]; //Accuracy/15 == % increase [Spell Effect: Accuracy)
|
||||
int32 HundredHands; //extra haste, stacks with all other haste i
|
||||
int32 MeleeLifetap; //i
|
||||
int32 Vampirism; //i
|
||||
int32 HealRate; // Spell effect that influences effectiveness of heals
|
||||
int32 MaxHPChange; // Spell Effect
|
||||
int16 SkillDmgTaken[HIGHEST_SKILL+2]; // All Skills + -1
|
||||
int16 SkillDmgTaken[EQEmu::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 HealAmt; // Item Effect
|
||||
int32 SpellDmg; // Item Effect
|
||||
int32 Clairvoyance; // Item Effect
|
||||
@@ -329,9 +350,9 @@ struct StatBonuses {
|
||||
uint32 SpellTriggers[MAX_SPELL_TRIGGER]; // Innate/Spell/Item Spells that trigger when you cast
|
||||
uint32 SpellOnKill[MAX_SPELL_TRIGGER*3]; // Chance to proc after killing a mob
|
||||
uint32 SpellOnDeath[MAX_SPELL_TRIGGER*2]; // Chance to have effect cast when you die
|
||||
int32 CritDmgMob[HIGHEST_SKILL+2]; // All Skills + -1
|
||||
int32 SkillReuseTime[HIGHEST_SKILL+1]; // Reduces skill timers
|
||||
int32 SkillDamageAmount[HIGHEST_SKILL+2]; // All Skills + -1
|
||||
int32 CritDmgMob[EQEmu::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 SkillReuseTime[EQEmu::skills::HIGHEST_SKILL + 1]; // Reduces skill timers
|
||||
int32 SkillDamageAmount[EQEmu::skills::HIGHEST_SKILL + 2]; // All Skills + -1
|
||||
int32 TwoHandBluntBlock; // chance to block when wielding two hand blunt weapon
|
||||
uint32 ItemManaRegenCap; // Increases the amount of mana you have can over the cap(aa effect)
|
||||
int32 GravityEffect; // Indictor of spell effect
|
||||
@@ -354,7 +375,7 @@ struct StatBonuses {
|
||||
uint8 FocusEffects[HIGHEST_FOCUS+1]; // Stores the focus effectid for each focustype you have.
|
||||
int16 FocusEffectsWorn[HIGHEST_FOCUS+1]; // Optional to allow focus effects to be applied additively from worn slot
|
||||
bool NegateEffects; // Check if you contain a buff with negate effect. (only spellbonuses)
|
||||
int32 SkillDamageAmount2[HIGHEST_SKILL+2]; // Adds skill specific damage
|
||||
int32 SkillDamageAmount2[EQEmu::skills::HIGHEST_SKILL + 2]; // Adds skill specific damage
|
||||
uint32 NegateAttacks[3]; // 0 = bool HasEffect 1 = Buff Slot 2 = Max damage absorbed per hit
|
||||
uint32 MitigateMeleeRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per hit 3 = Rune Amt
|
||||
uint32 MeleeThresholdGuard[3]; // 0 = Mitigation value 1 = Buff Slot 2 = Min damage to trigger.
|
||||
@@ -387,10 +408,11 @@ struct StatBonuses {
|
||||
int32 Metabolism; // Food/drink consumption rates.
|
||||
bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others.
|
||||
int32 FactionModPct; // Modifies amount of faction gained.
|
||||
int32 MeleeVulnerability; // Weakness/mitigation to melee damage
|
||||
bool LimitToSkill[HIGHEST_SKILL+2]; // Determines if we need to search for a skill proc.
|
||||
bool LimitToSkill[EQEmu::skills::HIGHEST_SKILL + 2]; // Determines if we need to search for a skill proc.
|
||||
uint32 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs.
|
||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||
uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier
|
||||
uint32 PC_Pet_Flurry; // Percent chance flurry from double attack
|
||||
|
||||
// AAs
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
@@ -399,7 +421,7 @@ struct StatBonuses {
|
||||
int8 BaseMovementSpeed; // Adjust base run speed, does not stack with other movement bonuses.
|
||||
uint8 IncreaseRunSpeedCap; // Increase max run speed above cap.
|
||||
int32 DoubleSpecialAttack; // Chance to to perform a double special attack (ie flying kick 2x)
|
||||
int32 SpecialAttackKBProc[2]; // Chance to to do a knockback from special attacks. (0 = chance 1 = Skill)
|
||||
int32 SkillAttackProc[3]; // [0] chance to proc [2] spell on [1] skill usage
|
||||
uint8 FrontalStunResist; // Chance to resist a frontal stun
|
||||
int32 BindWound; // Increase amount of HP by percent.
|
||||
int32 MaxBindWound; // Increase max amount of HP you can bind wound.
|
||||
@@ -421,7 +443,7 @@ struct StatBonuses {
|
||||
int32 CombatStability; // Melee damage mitigation.
|
||||
int32 DoubleRiposte; // Chance to double riposte
|
||||
int32 GiveDoubleRiposte[3]; // 0=Regular Chance, 1=Skill Attack Chance, 2=Skill
|
||||
uint32 RaiseSkillCap[2]; // Raise a specific skill cap (1 = value, 2=skill)
|
||||
uint32 RaiseSkillCap[EQEmu::skills::HIGHEST_SKILL + 1]; // Raise a specific skill cap (base1= value, base2=skill)
|
||||
int32 Ambidexterity; // Increase chance to duel wield by adding bonus 'skill'.
|
||||
int32 PetMaxHP; // Increase the max hp of your pet.
|
||||
int32 PetFlurry; // Chance for pet to flurry.
|
||||
@@ -438,7 +460,7 @@ struct StatBonuses {
|
||||
int32 ShieldEquipHateMod; // Hate mod when shield equiped.
|
||||
int32 ShieldEquipDmgMod[2]; // Damage mod when shield equiped. 0 = damage modifier 1 = Unknown
|
||||
bool TriggerOnValueAmount; // Triggers off various different conditions, bool to check if client has effect.
|
||||
int8 StunBashChance; // chance to stun with bash.
|
||||
int8 StunBashChance; // chance to stun with bash.
|
||||
int8 IncreaseChanceMemwipe; // increases chance to memory wipe
|
||||
int8 CriticalMend; // chance critical monk mend
|
||||
int32 ImprovedReclaimEnergy; // Modifies amount of mana returned from reclaim energy
|
||||
@@ -448,6 +470,13 @@ struct StatBonuses {
|
||||
uint8 AssassinateLevel; // Max Level Assassinate will be effective at.
|
||||
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
||||
bool IllusionPersistence; // Causes illusions not to fade.
|
||||
uint16 extra_xtargets; // extra xtarget entries
|
||||
bool ShroudofStealth; // rogue improved invisiblity
|
||||
uint16 ReduceFallDamage; // reduce fall damage by percent
|
||||
int32 ReduceTradeskillFail[EQEmu::skills::HIGHEST_SKILL + 1]; // Reduces chance for trade skills to fail by percent.
|
||||
uint8 TradeSkillMastery; // Allow number of tradeskills to exceed 200 skill.
|
||||
int16 NoBreakAESneak; // Percent value
|
||||
int16 FeignedCastOnChance; // Percent Value
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -455,6 +484,7 @@ typedef struct
|
||||
uint16 spellID;
|
||||
uint16 chance;
|
||||
uint16 base_spellID;
|
||||
int level_override;
|
||||
} tProc;
|
||||
|
||||
struct Shielders_Struct {
|
||||
@@ -484,7 +514,7 @@ typedef struct
|
||||
//make DoAnim take it instead of int, to enforce its use.
|
||||
enum { //type arguments to DoAnim
|
||||
animKick = 1,
|
||||
animPiercing = 2, //might be piercing?
|
||||
anim1HPiercing = 2, //might be piercing?
|
||||
anim2HSlashing = 3,
|
||||
anim2HWeapon = 4,
|
||||
anim1HWeapon = 5,
|
||||
@@ -507,7 +537,8 @@ typedef enum {
|
||||
petOther,
|
||||
petCharmed,
|
||||
petNPCFollow,
|
||||
petTargetLock //remain active as long something is on the hatelist. Don't listen to any commands
|
||||
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||
petNone = 0xFF // not a pet
|
||||
} PetType;
|
||||
|
||||
typedef enum {
|
||||
@@ -586,7 +617,8 @@ struct ExtraAttackOptions {
|
||||
: damage_percent(1.0f), damage_flat(0),
|
||||
armor_pen_percent(0.0f), armor_pen_flat(0),
|
||||
crit_percent(1.0f), crit_flat(0.0f),
|
||||
hate_percent(1.0f), hate_flat(0), hit_chance(0)
|
||||
hate_percent(1.0f), hate_flat(0), hit_chance(0),
|
||||
melee_damage_bonus_flat(0), skilldmgtaken_bonus_flat(0)
|
||||
{ }
|
||||
|
||||
float damage_percent;
|
||||
@@ -598,6 +630,9 @@ struct ExtraAttackOptions {
|
||||
float hate_percent;
|
||||
int hate_flat;
|
||||
int hit_chance;
|
||||
int melee_damage_bonus_flat;
|
||||
int skilldmgtaken_bonus_flat;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+134
-124
@@ -22,8 +22,10 @@ Child of the Mob class.
|
||||
*/
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#if (!defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1900))
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
@@ -32,6 +34,7 @@ Child of the Mob class.
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/say_link.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "corpse.h"
|
||||
@@ -57,15 +60,15 @@ extern WorldServer worldserver;
|
||||
extern npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
||||
|
||||
void Corpse::SendEndLootErrorPacket(Client* client) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_LootComplete, 0);
|
||||
auto outapp = new EQApplicationPacket(OP_LootComplete, 0);
|
||||
client->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||
void Corpse::SendLootReqErrorPacket(Client* client, LootResponse response) {
|
||||
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
||||
d->response = response;
|
||||
d->response = static_cast<uint8>(response);
|
||||
d->unknown1 = 0x5a;
|
||||
d->unknown2 = 0x40;
|
||||
client->QueuePacket(outapp);
|
||||
@@ -74,7 +77,8 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) {
|
||||
|
||||
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) {
|
||||
uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
|
||||
char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
|
||||
auto buffer =
|
||||
new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
|
||||
PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
|
||||
database.LoadCharacterCorpseData(in_dbid, pcs);
|
||||
|
||||
@@ -88,41 +92,40 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
}
|
||||
|
||||
/* Create Corpse Entity */
|
||||
Corpse* pc = new Corpse(
|
||||
in_dbid, // uint32 in_dbid
|
||||
in_charid, // uint32 in_charid
|
||||
in_charname.c_str(), // char* in_charname
|
||||
&itemlist, // ItemList* in_itemlist
|
||||
pcs->copper, // uint32 in_copper
|
||||
pcs->silver, // uint32 in_silver
|
||||
pcs->gold, // uint32 in_gold
|
||||
pcs->plat, // uint32 in_plat
|
||||
position,
|
||||
pcs->size, // float in_size
|
||||
pcs->gender, // uint8 in_gender
|
||||
pcs->race, // uint16 in_race
|
||||
pcs->class_, // uint8 in_class
|
||||
pcs->deity, // uint8 in_deity
|
||||
pcs->level, // uint8 in_level
|
||||
pcs->texture, // uint8 in_texture
|
||||
pcs->helmtexture, // uint8 in_helmtexture
|
||||
pcs->exp, // uint32 in_rezexp
|
||||
was_at_graveyard // bool wasAtGraveyard
|
||||
);
|
||||
auto pc = new Corpse(in_dbid, // uint32 in_dbid
|
||||
in_charid, // uint32 in_charid
|
||||
in_charname.c_str(), // char* in_charname
|
||||
&itemlist, // ItemList* in_itemlist
|
||||
pcs->copper, // uint32 in_copper
|
||||
pcs->silver, // uint32 in_silver
|
||||
pcs->gold, // uint32 in_gold
|
||||
pcs->plat, // uint32 in_plat
|
||||
position,
|
||||
pcs->size, // float in_size
|
||||
pcs->gender, // uint8 in_gender
|
||||
pcs->race, // uint16 in_race
|
||||
pcs->class_, // uint8 in_class
|
||||
pcs->deity, // uint8 in_deity
|
||||
pcs->level, // uint8 in_level
|
||||
pcs->texture, // uint8 in_texture
|
||||
pcs->helmtexture, // uint8 in_helmtexture
|
||||
pcs->exp, // uint32 in_rezexp
|
||||
was_at_graveyard // bool wasAtGraveyard
|
||||
);
|
||||
|
||||
if (pcs->locked)
|
||||
pc->Lock();
|
||||
|
||||
/* Load Item Tints */
|
||||
pc->item_tint[0].Color = pcs->item_tint[0].Color;
|
||||
pc->item_tint[1].Color = pcs->item_tint[1].Color;
|
||||
pc->item_tint[2].Color = pcs->item_tint[2].Color;
|
||||
pc->item_tint[3].Color = pcs->item_tint[3].Color;
|
||||
pc->item_tint[4].Color = pcs->item_tint[4].Color;
|
||||
pc->item_tint[5].Color = pcs->item_tint[5].Color;
|
||||
pc->item_tint[6].Color = pcs->item_tint[6].Color;
|
||||
pc->item_tint[7].Color = pcs->item_tint[7].Color;
|
||||
pc->item_tint[8].Color = pcs->item_tint[8].Color;
|
||||
pc->item_tint.Head.Color = pcs->item_tint.Head.Color;
|
||||
pc->item_tint.Chest.Color = pcs->item_tint.Chest.Color;
|
||||
pc->item_tint.Arms.Color = pcs->item_tint.Arms.Color;
|
||||
pc->item_tint.Wrist.Color = pcs->item_tint.Wrist.Color;
|
||||
pc->item_tint.Hands.Color = pcs->item_tint.Hands.Color;
|
||||
pc->item_tint.Legs.Color = pcs->item_tint.Legs.Color;
|
||||
pc->item_tint.Feet.Color = pcs->item_tint.Feet.Color;
|
||||
pc->item_tint.Primary.Color = pcs->item_tint.Primary.Color;
|
||||
pc->item_tint.Secondary.Color = pcs->item_tint.Secondary.Color;
|
||||
|
||||
/* Load Physical Appearance */
|
||||
pc->haircolor = pcs->haircolor;
|
||||
@@ -138,10 +141,8 @@ Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std:
|
||||
pc->IsRezzed(rezzed);
|
||||
pc->become_npc = false;
|
||||
|
||||
pc->m_Light.Level.Innate = pc->m_Light.Type.Innate = 0;
|
||||
pc->UpdateEquipmentLight(); // itemlist populated above..need to determine actual values
|
||||
pc->m_Light.Level.Spell = pc->m_Light.Type.Spell = 0;
|
||||
|
||||
|
||||
safe_delete_array(pcs);
|
||||
|
||||
return pc;
|
||||
@@ -153,7 +154,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
|
||||
in_npc->GetPosition(), in_npc->GetInnateLightType(), in_npc->GetTexture(),in_npc->GetHelmTexture(),
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0),
|
||||
0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
|
||||
corpse_decay_timer(in_decaytime),
|
||||
corpse_rez_timer(0),
|
||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||
@@ -162,8 +163,6 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
{
|
||||
corpse_graveyard_timer.Disable();
|
||||
|
||||
memset(item_tint, 0, sizeof(item_tint));
|
||||
|
||||
is_corpse_changed = false;
|
||||
is_player_corpse = false;
|
||||
is_locked = false;
|
||||
@@ -244,7 +243,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
client->GetPP().drakkin_heritage, // uint32 in_drakkin_heritage,
|
||||
client->GetPP().drakkin_tattoo, // uint32 in_drakkin_tattoo,
|
||||
client->GetPP().drakkin_details, // uint32 in_drakkin_details,
|
||||
0, // uint32 in_armor_tint[_MaterialCount],
|
||||
EQEmu::TintProfile(), // uint32 in_armor_tint[_MaterialCount],
|
||||
0xff, // uint8 in_aa_title,
|
||||
0, // uint8 in_see_invis, // see through invis
|
||||
0, // uint8 in_see_invis_undead, // see through invis vs. undead
|
||||
@@ -254,7 +253,12 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
0, // int32 in_mana_regen,
|
||||
0, // uint8 in_qglobal,
|
||||
0, // uint8 in_maxlevel,
|
||||
0 // uint32 in_scalerate
|
||||
0, // uint32 in_scalerate
|
||||
0, // uint8 in_armtexture,
|
||||
0, // uint8 in_bracertexture,
|
||||
0, // uint8 in_handtexture,
|
||||
0, // uint8 in_legtexture,
|
||||
0 // uint8 in_feettexture,
|
||||
),
|
||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||
@@ -272,8 +276,6 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
corpse_graveyard_timer.Disable();
|
||||
}
|
||||
|
||||
memset(item_tint, 0, sizeof(item_tint));
|
||||
|
||||
for (i = 0; i < MAX_LOOTERS; i++){
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
@@ -307,7 +309,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
// cash
|
||||
// Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't.
|
||||
// (change to first client that supports 'death hover' mode, if not SoF.)
|
||||
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < ClientVersion::SoF) {
|
||||
if (!RuleB(Character, RespawnFromHover) || client->ClientVersion() < EQEmu::versions::ClientVersion::SoF) {
|
||||
SetCash(pp->copper, pp->silver, pp->gold, pp->platinum);
|
||||
pp->copper = 0;
|
||||
pp->silver = 0;
|
||||
@@ -316,18 +318,18 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
}
|
||||
|
||||
// get their tints
|
||||
memcpy(item_tint, &client->GetPP().item_tint, sizeof(item_tint));
|
||||
memcpy(&item_tint.Slot, &client->GetPP().item_tint, sizeof(item_tint));
|
||||
|
||||
// TODO soulbound items need not be added to corpse, but they need
|
||||
// to go into the regular slots on the player, out of bags
|
||||
std::list<uint32> removed_list;
|
||||
|
||||
for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; ++i) {
|
||||
if(i == MainAmmo && client->GetClientVersion() >= ClientVersion::SoF) {
|
||||
item = client->GetInv().GetItem(MainPowerSource);
|
||||
for (i = SLOT_BEGIN; i < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; ++i) {
|
||||
if (i == EQEmu::legacy::SlotAmmo && client->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
item = client->GetInv().GetItem(EQEmu::legacy::SlotPowerSource);
|
||||
if (item != nullptr) {
|
||||
if (!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent))
|
||||
MoveItemToCorpse(client, item, MainPowerSource, removed_list);
|
||||
MoveItemToCorpse(client, item, EQEmu::legacy::SlotPowerSource, removed_list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,10 +405,10 @@ void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, s
|
||||
removedList.push_back(equipSlot);
|
||||
|
||||
while (true) {
|
||||
if (!inst->IsType(ItemClassContainer)) { break; }
|
||||
if (equipSlot < EmuConstants::GENERAL_BEGIN || equipSlot > MainCursor) { break; }
|
||||
if (!inst->IsClassBag()) { break; }
|
||||
if (equipSlot < EQEmu::legacy::GENERAL_BEGIN || equipSlot > EQEmu::legacy::SlotCursor) { break; }
|
||||
|
||||
for (auto sub_index = SUB_BEGIN; sub_index < EmuConstants::ITEM_CONTAINER_SIZE; ++sub_index) {
|
||||
for (auto sub_index = SUB_INDEX_BEGIN; sub_index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++sub_index) {
|
||||
int16 real_bag_slot = Inventory::CalcSlotId(equipSlot, sub_index);
|
||||
auto bag_inst = client->GetInv().GetItem(real_bag_slot);
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
@@ -469,7 +471,7 @@ in_helmtexture,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
EQEmu::TintProfile(),
|
||||
0xff,
|
||||
0,
|
||||
0,
|
||||
@@ -479,6 +481,11 @@ in_helmtexture,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0),
|
||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||
@@ -492,8 +499,6 @@ in_helmtexture,
|
||||
if (!zone->HasGraveyard() || wasAtGraveyard)
|
||||
corpse_graveyard_timer.Disable();
|
||||
|
||||
memset(item_tint, 0, sizeof(item_tint));
|
||||
|
||||
is_corpse_changed = false;
|
||||
is_player_corpse = true;
|
||||
is_locked = false;
|
||||
@@ -520,7 +525,6 @@ in_helmtexture,
|
||||
SetPlayerKillItemID(0);
|
||||
|
||||
UpdateEquipmentLight();
|
||||
m_Light.Level.Spell = m_Light.Type.Spell = 0;
|
||||
UpdateActiveLight();
|
||||
}
|
||||
|
||||
@@ -582,7 +586,7 @@ bool Corpse::Save() {
|
||||
dbpc->helmtexture = this->helmtexture;
|
||||
dbpc->exp = rez_experience;
|
||||
|
||||
memcpy(dbpc->item_tint, item_tint, sizeof(dbpc->item_tint));
|
||||
memcpy(&dbpc->item_tint.Slot, &item_tint.Slot, sizeof(dbpc->item_tint));
|
||||
dbpc->haircolor = haircolor;
|
||||
dbpc->beardcolor = beardcolor;
|
||||
dbpc->eyecolor2 = eyecolor1;
|
||||
@@ -657,7 +661,7 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
|
||||
|
||||
is_corpse_changed = true;
|
||||
|
||||
ServerLootItem_Struct* item = new ServerLootItem_Struct;
|
||||
auto item = new ServerLootItem_Struct;
|
||||
|
||||
memset(item, 0, sizeof(ServerLootItem_Struct));
|
||||
item->item_id = itemnum;
|
||||
@@ -689,7 +693,7 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct**
|
||||
}
|
||||
|
||||
if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) {
|
||||
int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_BEGIN);
|
||||
int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_INDEX_BEGIN);
|
||||
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
@@ -744,7 +748,7 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data)
|
||||
itemlist.erase(iter);
|
||||
|
||||
uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
|
||||
if (material != _MaterialInvalid)
|
||||
if (material != EQEmu::textures::TextureInvalid)
|
||||
SendWearChange(material);
|
||||
|
||||
UpdateEquipmentLight();
|
||||
@@ -797,7 +801,7 @@ bool Corpse::Process() {
|
||||
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
|
||||
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint());
|
||||
corpse_graveyard_timer.Disable();
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
|
||||
SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
|
||||
spc->player_corpse_id = corpse_db_id;
|
||||
spc->zone_id = zone->graveyard_zoneid();
|
||||
@@ -833,7 +837,7 @@ bool Corpse::Process() {
|
||||
Save();
|
||||
player_corpse_depop = true;
|
||||
corpse_db_id = 0;
|
||||
Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has burried.", this->GetName());
|
||||
Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has buried.", this->GetName());
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName());
|
||||
@@ -879,9 +883,8 @@ void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
|
||||
|
||||
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) {
|
||||
// Added 12/08. Started compressing loot struct on live.
|
||||
char tmp[10];
|
||||
if(player_corpse_depop) {
|
||||
SendLootReqErrorPacket(client, 0);
|
||||
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -893,7 +896,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
}
|
||||
|
||||
if(is_locked && client->Admin() < 100) {
|
||||
SendLootReqErrorPacket(client, 0);
|
||||
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||
client->Message(13, "Error: Corpse locked by GM.");
|
||||
return;
|
||||
}
|
||||
@@ -904,17 +907,24 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
if(this->being_looted_by != 0xFFFFFFFF) {
|
||||
// lets double check....
|
||||
Entity* looter = entity_list.GetID(this->being_looted_by);
|
||||
if(looter == 0)
|
||||
if(looter == nullptr)
|
||||
this->being_looted_by = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint8 Loot_Request_Type = 1;
|
||||
bool loot_coin = false;
|
||||
if(database.GetVariable("LootCoin", tmp, 9))
|
||||
loot_coin = (atoi(tmp) == 1);
|
||||
std::string tmp;
|
||||
if(database.GetVariable("LootCoin", tmp))
|
||||
loot_coin = tmp[0] == 1 && tmp[1] == '\0';
|
||||
|
||||
if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
|
||||
SendLootReqErrorPacket(client, 0);
|
||||
if (DistanceSquaredNoZ(client->GetPosition(), m_Position) > 625) {
|
||||
SendLootReqErrorPacket(client, LootResponse::TooFar);
|
||||
// not sure if we need to send the packet back in this case? Didn't before!
|
||||
// Will just return for now
|
||||
return;
|
||||
}
|
||||
else if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
|
||||
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||
Loot_Request_Type = 0;
|
||||
}
|
||||
else if (IsPlayerCorpse() && char_id == client->CharacterID()) {
|
||||
@@ -935,16 +945,17 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
|
||||
if (Loot_Request_Type == 1) {
|
||||
if (client->Admin() < 100 || !client->GetGM()) {
|
||||
SendLootReqErrorPacket(client, 2);
|
||||
SendLootReqErrorPacket(client, LootResponse::NotAtThisTime);
|
||||
}
|
||||
}
|
||||
|
||||
if(Loot_Request_Type >= 2 || (Loot_Request_Type == 1 && client->Admin() >= 100 && client->GetGM())) {
|
||||
client->CommonBreakInvisible(); // we should be "all good" so lets break invis now instead of earlier before all error checking is done
|
||||
this->being_looted_by = client->GetID();
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
||||
|
||||
d->response = 1;
|
||||
d->response = static_cast<uint8>(LootResponse::Normal);
|
||||
d->unknown1 = 0x42;
|
||||
d->unknown2 = 0xef;
|
||||
|
||||
@@ -976,12 +987,12 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
safe_delete(outapp);
|
||||
if(Loot_Request_Type == 5) {
|
||||
int pkitem = GetPlayerKillItem();
|
||||
const Item_Struct* item = database.GetItem(pkitem);
|
||||
const EQEmu::ItemBase* item = database.GetItem(pkitem);
|
||||
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
client->SendItemPacket(EQEmu::legacy::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
}
|
||||
else { client->Message(13, "Could not find item number %i to send!!", GetPlayerKillItem()); }
|
||||
@@ -991,12 +1002,12 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
const Item_Struct* item = 0;
|
||||
const EQEmu::ItemBase* item = 0;
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
|
||||
int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, client->GetClientVersion());
|
||||
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToInventoryVersion(client->ClientVersion()))->InventoryTypeSize[EQEmu::legacy::TypeCorpse];
|
||||
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item_data = *cur;
|
||||
@@ -1005,7 +1016,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
// Dont display the item if it's in a bag
|
||||
|
||||
// Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse.
|
||||
if(!IsPlayerCorpse() || item_data->equip_slot <= MainCursor || item_data->equip_slot == MainPowerSource || Loot_Request_Type>=3 ||
|
||||
if (!IsPlayerCorpse() || item_data->equip_slot <= EQEmu::legacy::SlotCursor || item_data->equip_slot == EQEmu::legacy::SlotPowerSource || Loot_Request_Type >= 3 ||
|
||||
(item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) {
|
||||
if(i < corpselootlimit) {
|
||||
item = database.GetItem(item_data->item_id);
|
||||
@@ -1014,8 +1025,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
// MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor
|
||||
client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
// SlotGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = SlotGeneral1 + SlotCursor
|
||||
client->SendItemPacket(i + EQEmu::legacy::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
@@ -1056,7 +1067,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
|
||||
// This is required for the 'Loot All' feature to work for SoD clients. I expect it is to tell the client that the
|
||||
// server has now sent all the items on the corpse.
|
||||
if(client->GetClientVersion() >= ClientVersion::SoD) { SendLootReqErrorPacket(client, 6); }
|
||||
if (client->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
|
||||
SendLootReqErrorPacket(client, LootResponse::LootAll);
|
||||
}
|
||||
|
||||
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
@@ -1096,7 +1108,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
return;
|
||||
}
|
||||
if (is_locked && client->Admin() < 100) {
|
||||
SendLootReqErrorPacket(client, 0);
|
||||
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||
client->Message(13, "Error: Corpse locked by GM.");
|
||||
return;
|
||||
}
|
||||
@@ -1106,7 +1118,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
being_looted_by = 0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
const Item_Struct* item = 0;
|
||||
const EQEmu::ItemBase* item = 0;
|
||||
ItemInst *inst = 0;
|
||||
ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10];
|
||||
|
||||
@@ -1115,10 +1127,10 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
item = database.GetItem(GetPlayerKillItem());
|
||||
}
|
||||
else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1){
|
||||
item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward
|
||||
item_data = GetItem(lootitem->slot_id - EQEmu::legacy::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward
|
||||
}
|
||||
else{
|
||||
item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN, bag_item_data);
|
||||
item_data = GetItem(lootitem->slot_id - EQEmu::legacy::CORPSE_BEGIN, bag_item_data);
|
||||
}
|
||||
|
||||
if (GetPlayerKillItem()<=1 && item_data != 0) {
|
||||
@@ -1144,7 +1156,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
}
|
||||
|
||||
if (inst->IsAugmented()) {
|
||||
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
|
||||
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
ItemInst *itm = inst->GetAugment(i);
|
||||
if (itm) {
|
||||
if (client->CheckLoreConflict(itm->GetItem())) {
|
||||
@@ -1159,9 +1171,9 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
}
|
||||
|
||||
char buf[88];
|
||||
char corpse_name[64];
|
||||
strcpy(corpse_name, corpse_name);
|
||||
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name));
|
||||
char q_corpse_name[64];
|
||||
strcpy(q_corpse_name, corpse_name);
|
||||
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(q_corpse_name));
|
||||
buf[87] = '\0';
|
||||
std::vector<EQEmu::Any> args;
|
||||
args.push_back(inst);
|
||||
@@ -1186,10 +1198,10 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
/* First add it to the looter - this will do the bag contents too */
|
||||
if (lootitem->auto_loot) {
|
||||
if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data))
|
||||
client->PutLootInInventory(MainCursor, *inst, bag_item_data);
|
||||
client->PutLootInInventory(EQEmu::legacy::SlotCursor, *inst, bag_item_data);
|
||||
}
|
||||
else {
|
||||
client->PutLootInInventory(MainCursor, *inst, bag_item_data);
|
||||
client->PutLootInInventory(EQEmu::legacy::SlotCursor, *inst, bag_item_data);
|
||||
}
|
||||
|
||||
/* Update any tasks that have an activity to loot this item */
|
||||
@@ -1205,8 +1217,8 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
}
|
||||
|
||||
/* Remove Bag Contents */
|
||||
if (item->ItemClass == ItemClassContainer && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) {
|
||||
for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
|
||||
if (item->IsClassBag() && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) {
|
||||
for (int i = SUB_INDEX_BEGIN; i < EQEmu::legacy::ITEM_CONTAINER_SIZE; i++) {
|
||||
if (bag_item_data[i]) {
|
||||
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
|
||||
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
|
||||
@@ -1221,8 +1233,8 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
}
|
||||
|
||||
/* Send message with item link to groups and such */
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemInst);
|
||||
EQEmu::SayLinkEngine linker;
|
||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||
linker.SetItemInst(inst);
|
||||
|
||||
auto item_link = linker.GenerateLink();
|
||||
@@ -1259,7 +1271,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
||||
}
|
||||
|
||||
void Corpse::EndLoot(Client* client, const EQApplicationPacket* app) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket;
|
||||
auto outapp = new EQApplicationPacket;
|
||||
outapp->SetOpcode(OP_LootComplete);
|
||||
outapp->size = 0;
|
||||
client->QueuePacket(outapp);
|
||||
@@ -1279,7 +1291,7 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
|
||||
ns->spawn.NPC = 2;
|
||||
|
||||
UpdateActiveLight();
|
||||
ns->spawn.light = m_Light.Type.Active;
|
||||
ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive];
|
||||
}
|
||||
|
||||
void Corpse::QueryLoot(Client* to) {
|
||||
@@ -1290,18 +1302,18 @@ void Corpse::QueryLoot(Client* to) {
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
|
||||
int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, to->GetClientVersion());
|
||||
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToInventoryVersion(to->ClientVersion()))->InventoryTypeSize[EQEmu::legacy::TypeCorpse];
|
||||
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* sitem = *cur;
|
||||
|
||||
if (IsPlayerCorpse()) {
|
||||
if (sitem->equip_slot >= EmuConstants::GENERAL_BAGS_BEGIN && sitem->equip_slot <= EmuConstants::CURSOR_BAG_END)
|
||||
if (sitem->equip_slot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && sitem->equip_slot <= EQEmu::legacy::CURSOR_BAG_END)
|
||||
sitem->lootslot = 0xFFFF;
|
||||
else
|
||||
x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF;
|
||||
|
||||
const Item_Struct* item = database.GetItem(sitem->item_id);
|
||||
const EQEmu::ItemBase* item = database.GetItem(sitem->item_id);
|
||||
|
||||
if (item)
|
||||
to->Message((sitem->lootslot == 0xFFFF), "LootSlot: %i (EquipSlot: %i) Item: %s (%d), Count: %i", static_cast<int16>(sitem->lootslot), sitem->equip_slot, item->Name, item->ID, sitem->charges);
|
||||
@@ -1315,7 +1327,7 @@ void Corpse::QueryLoot(Client* to) {
|
||||
}
|
||||
else {
|
||||
sitem->lootslot=y;
|
||||
const Item_Struct* item = database.GetItem(sitem->item_id);
|
||||
const EQEmu::ItemBase* item = database.GetItem(sitem->item_id);
|
||||
|
||||
if (item)
|
||||
to->Message(0, "LootSlot: %i Item: %s (%d), Count: %i", sitem->lootslot, item->Name, item->ID, sitem->charges);
|
||||
@@ -1389,7 +1401,7 @@ void Corpse::CompleteResurrection(){
|
||||
}
|
||||
|
||||
void Corpse::Spawn() {
|
||||
EQApplicationPacket* app = new EQApplicationPacket;
|
||||
auto app = new EQApplicationPacket;
|
||||
this->CreateSpawnPacket(app, this);
|
||||
entity_list.QueueClients(this, app);
|
||||
safe_delete(app);
|
||||
@@ -1398,7 +1410,7 @@ void Corpse::Spawn() {
|
||||
uint32 Corpse::GetEquipment(uint8 material_slot) const {
|
||||
int16 invslot;
|
||||
|
||||
if(material_slot > EmuConstants::MATERIAL_END) {
|
||||
if (material_slot > EQEmu::textures::LastTexture) {
|
||||
return NO_ITEM;
|
||||
}
|
||||
|
||||
@@ -1410,17 +1422,15 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const {
|
||||
}
|
||||
|
||||
uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
|
||||
const Item_Struct *item;
|
||||
const EQEmu::ItemBase *item;
|
||||
|
||||
if(material_slot > EmuConstants::MATERIAL_END) {
|
||||
if (material_slot > EQEmu::textures::LastTexture) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
item = database.GetItem(GetEquipment(material_slot));
|
||||
if(item != NO_ITEM) {
|
||||
return item_tint[material_slot].RGB.UseTint ?
|
||||
item_tint[material_slot].Color :
|
||||
item->Color;
|
||||
return (item_tint.Slot[material_slot].UseTint ? item_tint.Slot[material_slot].Color : item->Color);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1428,38 +1438,38 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
|
||||
|
||||
void Corpse::UpdateEquipmentLight()
|
||||
{
|
||||
m_Light.Type.Equipment = 0;
|
||||
m_Light.Level.Equipment = 0;
|
||||
m_Light.Type[EQEmu::lightsource::LightEquipment] = 0;
|
||||
m_Light.Level[EQEmu::lightsource::LightEquipment] = 0;
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
if (((*iter)->equip_slot < EmuConstants::EQUIPMENT_BEGIN || (*iter)->equip_slot > EmuConstants::EQUIPMENT_END) && (*iter)->equip_slot != MainPowerSource) { continue; }
|
||||
if ((*iter)->equip_slot == MainAmmo) { continue; }
|
||||
if (((*iter)->equip_slot < EQEmu::legacy::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::legacy::EQUIPMENT_END) && (*iter)->equip_slot != EQEmu::legacy::SlotPowerSource) { continue; }
|
||||
if ((*iter)->equip_slot == EQEmu::legacy::SlotAmmo) { continue; }
|
||||
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
|
||||
if (m_Light.IsLevelGreater(item->Light, m_Light.Type.Equipment))
|
||||
m_Light.Type.Equipment = item->Light;
|
||||
if (EQEmu::lightsource::IsLevelGreater(item->Light, m_Light.Type[EQEmu::lightsource::LightEquipment]))
|
||||
m_Light.Type[EQEmu::lightsource::LightEquipment] = item->Light;
|
||||
}
|
||||
|
||||
uint8 general_light_type = 0;
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
if ((*iter)->equip_slot < EmuConstants::GENERAL_BEGIN || (*iter)->equip_slot > EmuConstants::GENERAL_END) { continue; }
|
||||
if ((*iter)->equip_slot < EQEmu::legacy::GENERAL_BEGIN || (*iter)->equip_slot > EQEmu::legacy::GENERAL_END) { continue; }
|
||||
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
|
||||
if (item->ItemClass != ItemClassCommon) { continue; }
|
||||
if (!item->IsClassCommon()) { continue; }
|
||||
if (item->Light < 9 || item->Light > 13) { continue; }
|
||||
|
||||
if (m_Light.TypeToLevel(item->Light))
|
||||
if (EQEmu::lightsource::TypeToLevel(item->Light))
|
||||
general_light_type = item->Light;
|
||||
}
|
||||
|
||||
if (m_Light.IsLevelGreater(general_light_type, m_Light.Type.Equipment))
|
||||
m_Light.Type.Equipment = general_light_type;
|
||||
if (EQEmu::lightsource::IsLevelGreater(general_light_type, m_Light.Type[EQEmu::lightsource::LightEquipment]))
|
||||
m_Light.Type[EQEmu::lightsource::LightEquipment] = general_light_type;
|
||||
|
||||
m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment);
|
||||
m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]);
|
||||
}
|
||||
|
||||
void Corpse::AddLooter(Mob* who) {
|
||||
|
||||
+5
-5
@@ -37,7 +37,7 @@ class Corpse : public Mob {
|
||||
public:
|
||||
|
||||
static void SendEndLootErrorPacket(Client* client);
|
||||
static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
|
||||
static void SendLootReqErrorPacket(Client* client, LootResponse response = LootResponse::NotAtThisTime);
|
||||
|
||||
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000);
|
||||
Corpse(Client* client, int32 in_rezexp);
|
||||
@@ -47,9 +47,9 @@ class Corpse : public Mob {
|
||||
static Corpse* LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard);
|
||||
|
||||
/* Corpse: General */
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; }
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
Timer corpse_delay_timer;
|
||||
Timer corpse_graveyard_timer;
|
||||
Timer loot_cooldown_timer; /* Delay between loot actions on the corpse entity */
|
||||
Color_Struct item_tint[9];
|
||||
EQEmu::TintProfile item_tint;
|
||||
|
||||
};
|
||||
|
||||
|
||||
+14
-13
@@ -115,7 +115,7 @@ bool Doors::Process()
|
||||
{
|
||||
if (opentype == 40 || GetTriggerType() == 1)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer;
|
||||
md->doorid = door_id;
|
||||
md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
|
||||
@@ -137,7 +137,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
Log.Out(Logs::Detail, Logs::Doors, " incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param);
|
||||
Log.Out(Logs::Detail, Logs::Doors, " size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str());
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer;
|
||||
md->doorid = door_id;
|
||||
/////////////////////////////////////////////////////////////////
|
||||
@@ -170,15 +170,16 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
if(!sender->GetPendingAdventureDoorClick())
|
||||
{
|
||||
sender->PendingAdventureDoorClick();
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_AdventureClickDoor, sizeof(ServerPlayerClickedAdventureDoor_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_AdventureClickDoor,
|
||||
sizeof(ServerPlayerClickedAdventureDoor_Struct));
|
||||
ServerPlayerClickedAdventureDoor_Struct *ads = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer;
|
||||
strcpy(ads->player, sender->GetName());
|
||||
ads->zone_id = zone->GetZoneID();
|
||||
ads->id = GetDoorDBID();
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +188,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
uint8 keepoffkeyring = GetNoKeyring();
|
||||
uint32 haskey = 0;
|
||||
uint32 playerkey = 0;
|
||||
const ItemInst *lockpicks = sender->GetInv().GetItem(MainCursor);
|
||||
const ItemInst *lockpicks = sender->GetInv().GetItem(EQEmu::legacy::SlotCursor);
|
||||
|
||||
haskey = sender->GetInv().HasItem(keyneeded, 1);
|
||||
|
||||
@@ -283,12 +284,12 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
|
||||
}
|
||||
else if(lockpicks != nullptr)
|
||||
{
|
||||
if(sender->GetSkill(SkillPickLock))
|
||||
if (sender->GetSkill(EQEmu::skills::SkillPickLock))
|
||||
{
|
||||
if(lockpicks->GetItem()->ItemType == ItemTypeLockPick)
|
||||
if(lockpicks->GetItem()->ItemType == EQEmu::item::ItemTypeLockPick)
|
||||
{
|
||||
float modskill=sender->GetSkill(SkillPickLock);
|
||||
sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1);
|
||||
float modskill = sender->GetSkill(EQEmu::skills::SkillPickLock);
|
||||
sender->CheckIncreaseSkill(EQEmu::skills::SkillPickLock, nullptr, 1);
|
||||
|
||||
Log.Out(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill);
|
||||
|
||||
@@ -447,7 +448,7 @@ void Doors::NPCOpen(NPC* sender, bool alt_mode)
|
||||
return;
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
|
||||
md->doorid = door_id;
|
||||
md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
|
||||
@@ -473,7 +474,7 @@ void Doors::NPCOpen(NPC* sender, bool alt_mode)
|
||||
|
||||
void Doors::ForceOpen(Mob *sender, bool alt_mode)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
|
||||
md->doorid = door_id;
|
||||
md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
|
||||
@@ -498,7 +499,7 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode)
|
||||
|
||||
void Doors::ForceClose(Mob *sender, bool alt_mode)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
|
||||
md->doorid = door_id;
|
||||
md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR; // change from original (open to close)
|
||||
@@ -527,7 +528,7 @@ void Doors::ToggleState(Mob *sender)
|
||||
return;
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||
MoveDoor_Struct* md=(MoveDoor_Struct*)outapp->pBuffer;
|
||||
md->doorid = door_id;
|
||||
|
||||
|
||||
+101
-46
@@ -73,6 +73,9 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
if (spell_id == SPELL_IMP_HARM_TOUCH && IsClient() && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
|
||||
chance = 100;
|
||||
|
||||
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance)
|
||||
chance = spells[spell_id].override_crit_chance;
|
||||
|
||||
if (zone->random.Roll(chance)) {
|
||||
Critical = true;
|
||||
ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;
|
||||
@@ -89,12 +92,13 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
if (IsClient() && GetClass() == WIZARD)
|
||||
ratio += RuleI(Spells, WizCritRatio); //Default is zero
|
||||
|
||||
|
||||
if (Critical){
|
||||
|
||||
value = value_BaseEffect*ratio/100;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage2, spell_id)/100;
|
||||
|
||||
value += int(value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
|
||||
|
||||
@@ -106,8 +110,12 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100;
|
||||
|
||||
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
value -= GetFocusEffect(focusFcDamageAmt2, spell_id);
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio / 100;
|
||||
|
||||
else if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
|
||||
|
||||
else if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
@@ -126,6 +134,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
value = value_BaseEffect;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage2, spell_id)/100;
|
||||
|
||||
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
|
||||
|
||||
@@ -137,8 +146,12 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id);
|
||||
|
||||
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
value -= GetFocusEffect(focusFcDamageAmt2, spell_id);
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
|
||||
|
||||
else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
@@ -161,7 +174,10 @@ int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
chance += itembonuses.CriticalDoTChance + spellbonuses.CriticalDoTChance + aabonuses.CriticalDoTChance;
|
||||
|
||||
if (spellbonuses.CriticalDotDecay)
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalDotDecay);
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalDotDecay);
|
||||
|
||||
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance)
|
||||
chance = spells[spell_id].override_crit_chance;
|
||||
|
||||
value_BaseEffect = value + (value*GetFocusEffect(focusFcBaseEffects, spell_id)/100);
|
||||
|
||||
@@ -170,11 +186,13 @@ int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
ratio += itembonuses.DotCritDmgIncrease + spellbonuses.DotCritDmgIncrease + aabonuses.DotCritDmgIncrease;
|
||||
value = value_BaseEffect*ratio/100;
|
||||
value += int(value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100)*ratio/100;
|
||||
value += int(value_BaseEffect*GetFocusEffect(focusImprovedDamage2, spell_id)/100)*ratio/100;
|
||||
value += int(value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
|
||||
value += int(value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100)*ratio/100;
|
||||
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
|
||||
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
|
||||
int(GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100) +
|
||||
GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
GetFocusEffect(focusFcDamageAmt, spell_id) +
|
||||
GetFocusEffect(focusFcDamageAmt2, spell_id);
|
||||
|
||||
if (extra_dmg) {
|
||||
int duration = CalcBuffDuration(this, this, spell_id);
|
||||
@@ -188,11 +206,13 @@ int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
value = value_BaseEffect;
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100;
|
||||
value += value_BaseEffect*GetFocusEffect(focusImprovedDamage2, spell_id)/100;
|
||||
value += value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
|
||||
value += value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100;
|
||||
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
|
||||
GetFocusEffect(focusFcDamageAmtCrit, spell_id) +
|
||||
GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
GetFocusEffect(focusFcDamageAmt, spell_id) +
|
||||
GetFocusEffect(focusFcDamageAmt2, spell_id);
|
||||
|
||||
if (extra_dmg) {
|
||||
int duration = CalcBuffDuration(this, this, spell_id);
|
||||
@@ -211,6 +231,9 @@ int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
|
||||
int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg)
|
||||
{
|
||||
if (RuleB(Spells, FlatItemExtraSpellAmt))
|
||||
return extra_spell_amt;
|
||||
|
||||
int total_cast_time = 0;
|
||||
|
||||
if (spells[spell_id].recast_time >= spells[spell_id].recovery_time)
|
||||
@@ -219,11 +242,11 @@ int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_s
|
||||
total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time;
|
||||
|
||||
if (total_cast_time > 0 && total_cast_time <= 2500)
|
||||
extra_spell_amt = extra_spell_amt*25/100;
|
||||
else if (total_cast_time > 2500 && total_cast_time < 7000)
|
||||
extra_spell_amt = extra_spell_amt*(167*((total_cast_time - 1000)/1000)) / 1000;
|
||||
else
|
||||
extra_spell_amt = extra_spell_amt * total_cast_time / 7000;
|
||||
extra_spell_amt = extra_spell_amt*25/100;
|
||||
else if (total_cast_time > 2500 && total_cast_time < 7000)
|
||||
extra_spell_amt = extra_spell_amt*(167*((total_cast_time - 1000)/1000)) / 1000;
|
||||
else
|
||||
extra_spell_amt = extra_spell_amt * total_cast_time / 7000;
|
||||
|
||||
if(extra_spell_amt*2 < base_spell_dmg)
|
||||
return 0;
|
||||
@@ -260,6 +283,9 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
if (spellbonuses.CriticalHealDecay)
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
|
||||
|
||||
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance)
|
||||
chance = spells[spell_id].override_crit_chance;
|
||||
|
||||
if(chance && (zone->random.Roll(chance))) {
|
||||
Critical = true;
|
||||
modifier = 2; //At present time no critical heal amount modifier SPA exists.
|
||||
@@ -270,7 +296,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
value += GetFocusEffect(focusFcHealAmt, spell_id);
|
||||
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
|
||||
|
||||
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5)
|
||||
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
|
||||
|
||||
value += value*target->GetHealRate(spell_id, this)/100;
|
||||
@@ -281,7 +307,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
if (Critical) {
|
||||
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
|
||||
OTHER_CRIT_HEAL, GetName(), itoa(value));
|
||||
|
||||
|
||||
if (IsClient())
|
||||
Message_StringID(MT_SpellCrits, YOU_CRIT_HEAL, itoa(value));
|
||||
}
|
||||
@@ -319,7 +345,7 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
cost *= 2;
|
||||
|
||||
// Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
|
||||
if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if(itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%17) - 1] >= GetLevel() - 5)
|
||||
{
|
||||
int16 mana_back = itembonuses.Clairvoyance * zone->random.Int(1, 100) / 100;
|
||||
// Doesnt generate mana, so best case is a free spell
|
||||
@@ -413,24 +439,20 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
|
||||
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
{
|
||||
if (spells[spell_id].not_extendable)
|
||||
return duration;
|
||||
|
||||
int increase = 100;
|
||||
increase += GetFocusEffect(focusSpellDuration, spell_id);
|
||||
int tic_inc = 0;
|
||||
tic_inc = GetFocusEffect(focusSpellDurByTic, spell_id);
|
||||
|
||||
// Only need this for clients, since the change was for bard songs, I assume we should keep non bard songs getting +1
|
||||
// However if its bard or not and is mez, charm or fear, we need to add 1 so that client is in sync
|
||||
if (IsClient() && !(IsShortDurationBuff(spell_id) && IsBardSong(spell_id)) ||
|
||||
IsFearSpell(spell_id) ||
|
||||
IsCharmSpell(spell_id) ||
|
||||
IsMezSpell(spell_id) ||
|
||||
IsBlindSpell(spell_id))
|
||||
tic_inc += 1;
|
||||
float focused = ((duration * increase) / 100.0f) + tic_inc;
|
||||
int ifocused = static_cast<int>(focused);
|
||||
|
||||
return (((duration * increase) / 100) + tic_inc);
|
||||
// 7.6 is rounded to 7, 8.6 is rounded to 9
|
||||
// 6 is 6, etc
|
||||
if (FCMP(focused, ifocused) || ifocused % 2) // equal or odd
|
||||
return ifocused;
|
||||
else // even and not equal round to odd
|
||||
return ifocused + 1;
|
||||
}
|
||||
|
||||
int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime)
|
||||
@@ -459,14 +481,14 @@ int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime)
|
||||
bool Client::TrainDiscipline(uint32 itemid) {
|
||||
|
||||
//get the item info
|
||||
const Item_Struct *item = database.GetItem(itemid);
|
||||
const EQEmu::ItemBase *item = database.GetItem(itemid);
|
||||
if(item == nullptr) {
|
||||
Message(13, "Unable to find the tome you turned in!");
|
||||
Log.Out(Logs::General, Logs::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(item->ItemClass != ItemClassCommon || item->ItemType != ItemTypeSpell) {
|
||||
if (!item->IsClassCommon() || item->ItemType != EQEmu::item::ItemTypeSpell) {
|
||||
Message(13, "Invalid item type, you cannot learn from this item.");
|
||||
//summon them the item back...
|
||||
SummonItem(itemid);
|
||||
@@ -558,6 +580,33 @@ bool Client::TrainDiscipline(uint32 itemid) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
void Client::TrainDiscBySpellID(int32 spell_id)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < MAX_PP_DISCIPLINES; i++) {
|
||||
if(m_pp.disciplines.values[i] == 0) {
|
||||
m_pp.disciplines.values[i] = spell_id;
|
||||
database.SaveCharacterDisc(this->CharacterID(), i, spell_id);
|
||||
SendDisciplineUpdate();
|
||||
Message(15, "You have learned a new combat ability!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Client::GetDiscSlotBySpellID(int32 spellid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAX_PP_DISCIPLINES; i++)
|
||||
{
|
||||
if(m_pp.disciplines.values[i] == spellid)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Client::SendDisciplineUpdate() {
|
||||
EQApplicationPacket app(OP_DisciplineUpdate, sizeof(Disciplines_Struct));
|
||||
Disciplines_Struct *d = (Disciplines_Struct*)app.pBuffer;
|
||||
@@ -613,10 +662,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(GetEndurance() > spell.EndurCost) {
|
||||
SetEndurance(GetEndurance() - spell.EndurCost);
|
||||
TryTriggerOnValueAmount(false, false, true);
|
||||
} else {
|
||||
if(GetEndurance() < spell.EndurCost) {
|
||||
Message(11, "You are too fatigued to use this skill right now.");
|
||||
return(false);
|
||||
}
|
||||
@@ -624,17 +670,23 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
|
||||
if(spell.recast_time > 0)
|
||||
{
|
||||
uint32 reduced_recast = spell.recast_time / 1000;
|
||||
reduced_recast -= GetFocusEffect(focusReduceRecastTime, spell_id);
|
||||
if(reduced_recast <= 0){
|
||||
auto focus = GetFocusEffect(focusReduceRecastTime, spell_id);
|
||||
// do stupid stuff because custom servers.
|
||||
// we really should be able to just do the -= focus but since custom servers could have shorter reuse timers
|
||||
// we have to make sure we don't underflow the uint32 ...
|
||||
// and yes, the focus effect can be used to increase the durations (spell 38944)
|
||||
if (focus > reduced_recast) {
|
||||
reduced_recast = 0;
|
||||
if (GetPTimers().Enabled((uint32)DiscTimer))
|
||||
GetPTimers().Clear(&database, (uint32)DiscTimer);
|
||||
} else {
|
||||
reduced_recast -= focus;
|
||||
}
|
||||
|
||||
if (reduced_recast > 0)
|
||||
CastSpell(spell_id, target, DISCIPLINE_SPELL_SLOT, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast);
|
||||
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast);
|
||||
else{
|
||||
CastSpell(spell_id, target, DISCIPLINE_SPELL_SLOT);
|
||||
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -642,7 +694,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
|
||||
}
|
||||
else
|
||||
{
|
||||
CastSpell(spell_id, target, DISCIPLINE_SPELL_SLOT);
|
||||
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
@@ -651,7 +703,7 @@ void Client::SendDisciplineTimer(uint32 timer_id, uint32 duration)
|
||||
{
|
||||
if (timer_id < MAX_DISCIPLINE_TIMERS)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DisciplineTimer, sizeof(DisciplineTimer_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_DisciplineTimer, sizeof(DisciplineTimer_Struct));
|
||||
DisciplineTimer_Struct *dts = (DisciplineTimer_Struct *)outapp->pBuffer;
|
||||
dts->TimerID = timer_id;
|
||||
dts->Duration = duration;
|
||||
@@ -660,10 +712,10 @@ void Client::SendDisciplineTimer(uint32 timer_id, uint32 duration)
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::AETaunt(Client* taunter, float range)
|
||||
void EntityList::AETaunt(Client* taunter, float range, int32 bonus_hate)
|
||||
{
|
||||
if (range == 0)
|
||||
range = 100; //arbitrary default...
|
||||
range = 40; //Live AE taunt range - Hardcoded.
|
||||
|
||||
range = range * range;
|
||||
|
||||
@@ -677,7 +729,7 @@ void EntityList::AETaunt(Client* taunter, float range)
|
||||
&& taunter->IsAttackAllowed(them)
|
||||
&& DistanceSquaredNoZ(taunter->GetPosition(), them->GetPosition()) <= range) {
|
||||
if (taunter->CheckLosFN(them)) {
|
||||
taunter->Taunt(them, true);
|
||||
taunter->Taunt(them, true,0,true,bonus_hate);
|
||||
}
|
||||
}
|
||||
++it;
|
||||
@@ -771,7 +823,7 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
}
|
||||
} else {
|
||||
if (spells[spell_id].aemaxtargets && iCounter < spells[spell_id].aemaxtargets)
|
||||
if (spells[spell_id].aemaxtargets && iCounter < spells[spell_id].aemaxtargets)
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
if (!spells[spell_id].aemaxtargets)
|
||||
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
|
||||
@@ -859,7 +911,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
|
||||
if (!center->CheckLosFN(curmob))
|
||||
continue;
|
||||
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
|
||||
// See notes in AESpell() above for more info.
|
||||
// See notes in AESpell() above for more info.
|
||||
if (caster->IsAttackAllowed(curmob, true))
|
||||
continue;
|
||||
if (caster->CheckAggro(curmob))
|
||||
@@ -873,7 +925,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
|
||||
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
|
||||
}
|
||||
|
||||
//Dook- Rampage and stuff for clients.
|
||||
// Rampage and stuff for clients. Normal and Duration rampages
|
||||
//NPCs handle it differently in Mob::Rampage
|
||||
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
||||
//Dook- Will need tweaking, currently no pets or players or horses
|
||||
@@ -891,7 +943,10 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
|
||||
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
||||
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
||||
) {
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
if (!attacker->IsClient() || attacker->GetClass() == MONK || attacker->GetClass() == RANGER)
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
else
|
||||
attacker->CastToClient()->DoAttackRounds(curmob, Hand, IsFromSpell);
|
||||
hit++;
|
||||
if (count != 0 && hit >= count)
|
||||
return;
|
||||
|
||||
+85
-41
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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
|
||||
@@ -9,11 +9,11 @@
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
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
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef EMBPERL
|
||||
@@ -113,7 +113,10 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_LEAVE_AREA",
|
||||
"EVENT_RESPAWN",
|
||||
"EVENT_DEATH_COMPLETE",
|
||||
"EVENT_UNHANDLED_OPCODE"
|
||||
"EVENT_UNHANDLED_OPCODE",
|
||||
"EVENT_TICK",
|
||||
"EVENT_SPAWN_ZONE",
|
||||
"EVENT_DEATH_ZONE",
|
||||
};
|
||||
|
||||
PerlembParser::PerlembParser() : perl(nullptr) {
|
||||
@@ -154,7 +157,7 @@ void PerlembParser::ReloadQuests() {
|
||||
spell_quest_status_.clear();
|
||||
}
|
||||
|
||||
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
||||
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
||||
uint32 extradata, bool global, std::vector<EQEmu::Any> *extra_pointers)
|
||||
{
|
||||
if(!perl)
|
||||
@@ -182,15 +185,31 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
|
||||
|
||||
int char_id = 0;
|
||||
ExportCharID(package_name, char_id, npcmob, mob);
|
||||
ExportQGlobals(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
package_name, npcmob, mob, char_id);
|
||||
|
||||
/* Check for QGlobal export event enable */
|
||||
if (parse->perl_event_export_settings[event].qglobals){
|
||||
ExportQGlobals(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest, package_name, npcmob, mob, char_id);
|
||||
}
|
||||
|
||||
//ExportGenericVariables();
|
||||
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
package_name, mob, npcmob);
|
||||
ExportZoneVariables(package_name);
|
||||
ExportItemVariables(package_name, mob);
|
||||
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
|
||||
/* Check for Mob export event enable */
|
||||
if (parse->perl_event_export_settings[event].mob){
|
||||
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest, package_name, mob, npcmob);
|
||||
}
|
||||
|
||||
/* Check for Zone export event enable */
|
||||
if (parse->perl_event_export_settings[event].zone){
|
||||
ExportZoneVariables(package_name);
|
||||
}
|
||||
|
||||
/* Check for Item export event enable */
|
||||
if (parse->perl_event_export_settings[event].item){
|
||||
ExportItemVariables(package_name, mob);
|
||||
}
|
||||
|
||||
/* Check for Event export event enable */
|
||||
if (parse->perl_event_export_settings[event].event_variables){
|
||||
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
|
||||
}
|
||||
|
||||
if(isPlayerQuest || isGlobalPlayerQuest){
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
|
||||
@@ -198,8 +217,7 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
|
||||
else if(isItemQuest) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, iteminst);
|
||||
}
|
||||
else if(isSpellQuest)
|
||||
{
|
||||
else if(isSpellQuest){
|
||||
if(mob) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
|
||||
} else {
|
||||
@@ -459,15 +477,15 @@ void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
|
||||
|
||||
std::stringstream package_name;
|
||||
package_name << "qst_item_" << item->GetID();
|
||||
|
||||
|
||||
if(!perl)
|
||||
return;
|
||||
|
||||
|
||||
auto iter = item_quest_status_.find(item->GetID());
|
||||
if(iter != item_quest_status_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
perl->eval_file(package_name.str().c_str(), filename.c_str());
|
||||
}
|
||||
@@ -480,7 +498,7 @@ void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
|
||||
item_quest_status_[item->GetID()] = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
item_quest_status_[item->GetID()] = questLoaded;
|
||||
}
|
||||
|
||||
@@ -821,10 +839,10 @@ void PerlembParser::MapFunctions() {
|
||||
);
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, QuestEventID event, NPC* npcmob, ItemInst* iteminst, Mob* mob, bool global)
|
||||
{
|
||||
if(event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
if(event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
event == EVENT_SPELL_EFFECT_NPC ||
|
||||
event == EVENT_SPELL_BUFF_TIC_CLIENT ||
|
||||
event == EVENT_SPELL_BUFF_TIC_NPC ||
|
||||
@@ -843,14 +861,14 @@ void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest
|
||||
isPlayerQuest = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
isItemQuest = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
NPC* npcmob, ItemInst* iteminst, bool global)
|
||||
{
|
||||
if(!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
|
||||
@@ -864,7 +882,7 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye
|
||||
}
|
||||
else if(isItemQuest) {
|
||||
// need a valid ItemInst pointer check here..unsure how to cancel this process
|
||||
const Item_Struct* item = iteminst->GetItem();
|
||||
const EQEmu::ItemBase* item = iteminst->GetItem();
|
||||
package_name = "qst_item_";
|
||||
package_name += itoa(item->ID);
|
||||
}
|
||||
@@ -897,7 +915,7 @@ void PerlembParser::ExportCharID(const std::string &package_name, int &char_id,
|
||||
ExportVar(package_name.c_str(), "charid", char_id);
|
||||
}
|
||||
|
||||
void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, NPC *npcmob, Mob *mob, int char_id) {
|
||||
//NPC quest
|
||||
if(!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest)
|
||||
@@ -953,8 +971,8 @@ void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest,
|
||||
{
|
||||
QGlobalCache::Combine(globalMap, zone_c->GetBucket(), npcmob->GetNPCTypeID(), char_id, zone->GetZoneID());
|
||||
}
|
||||
|
||||
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||
|
||||
auto iter = globalMap.begin();
|
||||
while(iter != globalMap.end())
|
||||
{
|
||||
globhash[(*iter).name] = (*iter).value;
|
||||
@@ -1002,7 +1020,7 @@ void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest,
|
||||
QGlobalCache::Combine(globalMap, zone_c->GetBucket(), 0, char_id, zone->GetZoneID());
|
||||
}
|
||||
|
||||
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||
auto iter = globalMap.begin();
|
||||
while(iter != globalMap.end())
|
||||
{
|
||||
globhash[(*iter).name] = (*iter).value;
|
||||
@@ -1013,8 +1031,8 @@ void PerlembParser::ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest,
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob)
|
||||
void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob)
|
||||
{
|
||||
uint8 fac = 0;
|
||||
if (mob && mob->IsClient()) {
|
||||
@@ -1027,15 +1045,15 @@ void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQu
|
||||
if (mob && npcmob && mob->IsClient()) {
|
||||
Client* client = mob->CastToClient();
|
||||
|
||||
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetRace(),
|
||||
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetRace(),
|
||||
client->GetClass(), client->GetDeity(), npcmob->GetPrimaryFaction(), npcmob);
|
||||
}
|
||||
}
|
||||
|
||||
if(mob) {
|
||||
ExportVar(package_name.c_str(), "name", mob->GetName());
|
||||
ExportVar(package_name.c_str(), "race", GetRaceName(mob->GetRace()));
|
||||
ExportVar(package_name.c_str(), "class", GetEQClassName(mob->GetClass()));
|
||||
ExportVar(package_name.c_str(), "race", GetRaceIDName(mob->GetRace()));
|
||||
ExportVar(package_name.c_str(), "class", GetClassIDName(mob->GetClass()));
|
||||
ExportVar(package_name.c_str(), "ulevel", mob->GetLevel());
|
||||
ExportVar(package_name.c_str(), "userid", mob->GetID());
|
||||
}
|
||||
@@ -1072,7 +1090,7 @@ void PerlembParser::ExportZoneVariables(std::string &package_name) {
|
||||
ExportVar(package_name.c_str(), "instanceid", zone->GetInstanceID());
|
||||
ExportVar(package_name.c_str(), "instanceversion", zone->GetInstanceVersion());
|
||||
TimeOfDay_Struct eqTime;
|
||||
zone->zone_time.getEQTimeOfDay( time(0), &eqTime);
|
||||
zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime);
|
||||
ExportVar(package_name.c_str(), "zonehour", eqTime.hour - 1);
|
||||
ExportVar(package_name.c_str(), "zonemin", eqTime.minute);
|
||||
ExportVar(package_name.c_str(), "zonetime", (eqTime.hour - 1) * 100 + eqTime.minute);
|
||||
@@ -1122,8 +1140,8 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) {
|
||||
#undef HASITEM_LAST
|
||||
#undef HASITEM_ISNULLITEM
|
||||
|
||||
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
|
||||
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
|
||||
{
|
||||
switch (event) {
|
||||
case EVENT_SAY: {
|
||||
@@ -1240,7 +1258,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ExportVar(package_name.c_str(), "target_zone_id", data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EVENT_CAST_ON:
|
||||
case EVENT_CAST:
|
||||
case EVENT_CAST_BEGIN: {
|
||||
@@ -1277,7 +1295,8 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
|
||||
case EVENT_PLAYER_PICKUP:{
|
||||
ExportVar(package_name.c_str(), "picked_up_id", data);
|
||||
break;
|
||||
ExportVar(package_name.c_str(), "picked_up_entity_id", extradata);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_AGGRO_SAY: {
|
||||
@@ -1320,6 +1339,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ExportVar(package_name.c_str(), "itemid", objid);
|
||||
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||
ExportVar(package_name.c_str(), "spell_id", iteminst->GetItem()->Click.Effect);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1357,16 +1377,17 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
|
||||
case EVENT_FORAGE_SUCCESS: {
|
||||
ExportVar(package_name.c_str(), "foraged_item", extradata);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_FISH_SUCCESS: {
|
||||
ExportVar(package_name.c_str(), "fished_item", extradata);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_CLICK_OBJECT: {
|
||||
ExportVar(package_name.c_str(), "objectid", data);
|
||||
ExportVar(package_name.c_str(), "clicker_id", extradata);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1397,6 +1418,29 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||
break;
|
||||
}
|
||||
case EVENT_DROP_ITEM: {
|
||||
ExportVar(package_name.c_str(), "quantity", iteminst->IsStackable() ? iteminst->GetCharges() : 1);
|
||||
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
|
||||
ExportVar(package_name.c_str(), "itemid", iteminst->GetItem()->ID);
|
||||
ExportVar(package_name.c_str(), "spell_id", iteminst->GetItem()->Click.Effect);
|
||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||
break;
|
||||
}
|
||||
case EVENT_SPAWN_ZONE: {
|
||||
Seperator sep(data);
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", sep.arg[0]);
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", sep.arg[1]);
|
||||
break;
|
||||
}
|
||||
case EVENT_DEATH_ZONE: {
|
||||
Seperator sep(data);
|
||||
ExportVar(package_name.c_str(), "killer_id", sep.arg[0]);
|
||||
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
||||
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
||||
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||
ExportVar(package_name.c_str(), "killed_npc_id", sep.arg[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
virtual std::string GetVar(std::string name);
|
||||
virtual void ReloadQuests();
|
||||
virtual uint32 GetIdentifier() { return 0xf8b05c11; }
|
||||
|
||||
private:
|
||||
Embperl *perl;
|
||||
|
||||
|
||||
+163
-21
@@ -1182,13 +1182,26 @@ XS(XS__settime);
|
||||
XS(XS__settime)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: settime(new_hour, new_min)");
|
||||
if (items < 2)
|
||||
Perl_croak(aTHX_ "Usage: settime(new_hour, new_min, [update_world = true])");
|
||||
|
||||
int new_hour = (int)SvIV(ST(0));
|
||||
int new_min = (int)SvIV(ST(1));
|
||||
if (items == 2){
|
||||
int new_hour = (int)SvIV(ST(0));
|
||||
int new_min = (int)SvIV(ST(1));
|
||||
quest_manager.settime(new_hour, new_min, true);
|
||||
}
|
||||
else if (items == 3){
|
||||
int new_hour = (int)SvIV(ST(0));
|
||||
int new_min = (int)SvIV(ST(1));
|
||||
|
||||
quest_manager.settime(new_hour, new_min);
|
||||
int update_world = (int)SvIV(ST(2));
|
||||
if (update_world == 1){
|
||||
quest_manager.settime(new_hour, new_min, true);
|
||||
}
|
||||
else{
|
||||
quest_manager.settime(new_hour, new_min, false);
|
||||
}
|
||||
}
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -1735,18 +1748,18 @@ XS(XS__clear_zone_flag)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__summonburriedplayercorpse);
|
||||
XS(XS__summonburriedplayercorpse)
|
||||
XS(XS__summonburiedplayercorpse);
|
||||
XS(XS__summonburiedplayercorpse)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 5)
|
||||
Perl_croak(aTHX_ "Usage: summonburriedplayercorpse(char_id,dest_x,dest_y,dest_z,dest_heading)");
|
||||
Perl_croak(aTHX_ "Usage: summonburiedplayercorpse(char_id,dest_x,dest_y,dest_z,dest_heading)");
|
||||
|
||||
bool RETVAL;
|
||||
uint32 char_id = (int)SvIV(ST(0));
|
||||
auto position = glm::vec4((float)SvIV(ST(1)), (float)SvIV(ST(2)), (float)SvIV(ST(3)),(float)SvIV(ST(4)));
|
||||
|
||||
RETVAL = quest_manager.summonburriedplayercorpse(char_id, position);
|
||||
RETVAL = quest_manager.summonburiedplayercorpse(char_id, position);
|
||||
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
@@ -1771,19 +1784,19 @@ XS(XS__summonallplayercorpses)
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__getplayerburriedcorpsecount);
|
||||
XS(XS__getplayerburriedcorpsecount)
|
||||
XS(XS__getplayerburiedcorpsecount);
|
||||
XS(XS__getplayerburiedcorpsecount)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: getplayerburriedcorpsecount(char_id)");
|
||||
Perl_croak(aTHX_ "Usage: getplayerburiedcorpsecount(char_id)");
|
||||
|
||||
uint32 RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
uint32 char_id = (int)SvIV(ST(0));
|
||||
|
||||
RETVAL = quest_manager.getplayerburriedcorpsecount(char_id);
|
||||
RETVAL = quest_manager.getplayerburiedcorpsecount(char_id);
|
||||
XSprePUSH; PUSHu((IV)RETVAL);
|
||||
|
||||
XSRETURN(1);
|
||||
@@ -1917,6 +1930,52 @@ XS(XS__repopzone)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__ConnectNodeToNode);
|
||||
XS(XS__ConnectNodeToNode)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 4)
|
||||
Perl_croak(aTHX_ "Usage: ConnectNodeToNode(node1, node2, teleport, doorid)");
|
||||
|
||||
int node1 = (int)SvIV(ST(0));
|
||||
int node2 = (int)SvIV(ST(1));
|
||||
int teleport = (int)SvIV(ST(2));
|
||||
int doorid = (int)SvIV(ST(3));
|
||||
|
||||
quest_manager.ConnectNodeToNode(node1, node2, teleport, doorid);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__AddNode);
|
||||
XS(XS__AddNode)
|
||||
{
|
||||
dXSARGS;
|
||||
//void QuestManager::AddNode(float x, float y, float z, float best_z, int32 requested_id);
|
||||
if (items < 3 || items > 5)
|
||||
Perl_croak(aTHX_ "Usage: AddNode(x, y, z, [best_z], [requested_id])");
|
||||
|
||||
int x = (int)SvIV(ST(0));
|
||||
int y = (int)SvIV(ST(1));
|
||||
int z = (int)SvIV(ST(2));
|
||||
int best_z = 0;
|
||||
int requested_id = 0;
|
||||
|
||||
if (items == 4)
|
||||
{
|
||||
best_z = (int)SvIV(ST(3));
|
||||
}
|
||||
else if (items == 5)
|
||||
{
|
||||
best_z = (int)SvIV(ST(3));
|
||||
requested_id = (int)SvIV(ST(4));
|
||||
}
|
||||
|
||||
quest_manager.AddNode(x, y, z, best_z, requested_id);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__npcrace);
|
||||
XS(XS__npcrace)
|
||||
{
|
||||
@@ -2324,11 +2383,19 @@ XS(XS__assigntask)
|
||||
{
|
||||
dXSARGS;
|
||||
unsigned int taskid;
|
||||
if(items == 1) {
|
||||
bool enforce_level_requirement = false;
|
||||
if(items == 1 || items == 2) {
|
||||
taskid = (int)SvIV(ST(0));
|
||||
quest_manager.assigntask(taskid);
|
||||
if (items == 2)
|
||||
{
|
||||
if ((int)SvIV(ST(1)) == 1)
|
||||
{
|
||||
enforce_level_requirement = true;
|
||||
}
|
||||
}
|
||||
quest_manager.assigntask(taskid, enforce_level_requirement);
|
||||
} else {
|
||||
Perl_croak(aTHX_ "Usage: assigntask(taskid)");
|
||||
Perl_croak(aTHX_ "Usage: assigntask(taskid, enforce_level_requirement)");
|
||||
}
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
@@ -2839,6 +2906,42 @@ XS(XS__DestroyInstance) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__UpdateInstanceTimer);
|
||||
XS(XS__UpdateInstanceTimer) {
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: UpdateInstanceTimer(instance_id, new_duration)");
|
||||
|
||||
uint16 instance_id = (uint16)SvUV(ST(0));
|
||||
uint32 new_duration = (uint32)SvUV(ST(1));
|
||||
quest_manager.UpdateInstanceTimer(instance_id, new_duration);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__GetInstanceTimer);
|
||||
XS(XS__GetInstanceTimer) {
|
||||
dXSARGS;
|
||||
if (items != 0)
|
||||
Perl_croak(aTHX_ "Usage: GetInstanceTimer()");
|
||||
|
||||
uint32 timer = quest_manager.GetInstanceTimer();
|
||||
|
||||
XSRETURN_UV(timer);
|
||||
}
|
||||
|
||||
XS(XS__GetInstanceTimerByID);
|
||||
XS(XS__GetInstanceTimerByID) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: GetInstanceTimerByID(instance_id)");
|
||||
|
||||
uint16 instance_id = (uint16)SvUV(ST(0));
|
||||
uint32 timer = quest_manager.GetInstanceTimerByID(instance_id);
|
||||
|
||||
XSRETURN_UV(timer);
|
||||
}
|
||||
|
||||
XS(XS__GetInstanceID);
|
||||
XS(XS__GetInstanceID) {
|
||||
dXSARGS;
|
||||
@@ -3214,13 +3317,22 @@ XS(XS__wearchange);
|
||||
XS(XS__wearchange)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: wearchange(slot, texture)");
|
||||
if (items < 2)
|
||||
Perl_croak(aTHX_ "Usage: wearchange(slot, texture, [hero_forge_model], [elite_material])");
|
||||
|
||||
uint8 slot = (int)SvUV(ST(0));
|
||||
uint16 texture = (int)SvUV(ST(1));
|
||||
|
||||
quest_manager.wearchange(slot, texture);
|
||||
uint32 hero_forge_model = 0;
|
||||
uint32 elite_material = 0;
|
||||
|
||||
if (items > 2)
|
||||
hero_forge_model = (int)SvUV(ST(2));
|
||||
|
||||
if (items > 3)
|
||||
elite_material = (int)SvUV(ST(3));
|
||||
|
||||
quest_manager.wearchange(slot, texture, hero_forge_model, elite_material);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -3429,6 +3541,16 @@ XS(XS__clear_npctype_cache)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__reloadzonestaticdata);
|
||||
XS(XS__reloadzonestaticdata)
|
||||
{
|
||||
dXSARGS;
|
||||
|
||||
quest_manager.ReloadZoneStaticData();
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__qs_send_query);
|
||||
XS(XS__qs_send_query)
|
||||
{
|
||||
@@ -3524,6 +3646,19 @@ XS(XS__debug)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__UpdateZoneHeader);
|
||||
XS(XS__UpdateZoneHeader) {
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: UpdateZoneHeader(type, value)");
|
||||
|
||||
std::string type = (std::string)SvPV_nolen(ST(0));
|
||||
std::string value = (std::string)SvPV_nolen(ST(1));
|
||||
quest_manager.UpdateZoneHeader(type, value);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is the callback perl will look for to setup the
|
||||
@@ -3559,6 +3694,9 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
|
||||
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
||||
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
||||
newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file);
|
||||
newXS(strcpy(buf, "GetInstanceTimer"), XS__GetInstanceTimer, file);
|
||||
newXS(strcpy(buf, "GetInstanceTimerByID"), XS__GetInstanceTimerByID, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
|
||||
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
||||
@@ -3643,7 +3781,7 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
|
||||
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
|
||||
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
|
||||
newXS(strcpy(buf, "getplayerburriedcorpsecount"), XS__getplayerburriedcorpsecount, file);
|
||||
newXS(strcpy(buf, "getplayerburiedcorpsecount"), XS__getplayerburiedcorpsecount, file);
|
||||
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
|
||||
newXS(strcpy(buf, "givecash"), XS__givecash, file);
|
||||
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
|
||||
@@ -3686,8 +3824,11 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
||||
newXS(strcpy(buf, "rain"), XS__rain, file);
|
||||
newXS(strcpy(buf, "rebind"), XS__rebind, file);
|
||||
newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file);
|
||||
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
||||
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
||||
newXS(strcpy(buf, "ConnectNodeToNode"), XS__ConnectNodeToNode, file);
|
||||
newXS(strcpy(buf, "AddNode"), XS__AddNode, file);
|
||||
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
||||
newXS(strcpy(buf, "respawn"), XS__respawn, file);
|
||||
newXS(strcpy(buf, "resume"), XS__resume, file);
|
||||
@@ -3730,7 +3871,7 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
|
||||
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
|
||||
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
|
||||
newXS(strcpy(buf, "summonburriedplayercorpse"), XS__summonburriedplayercorpse, file);
|
||||
newXS(strcpy(buf, "summonburiedplayercorpse"), XS__summonburiedplayercorpse, file);
|
||||
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
|
||||
newXS(strcpy(buf, "surname"), XS__surname, file);
|
||||
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
|
||||
@@ -3747,6 +3888,7 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
|
||||
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
|
||||
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
|
||||
newXS(strcpy(buf, "UpdateZoneHeader"), XS__UpdateZoneHeader, file);
|
||||
newXS(strcpy(buf, "varlink"), XS__varlink, file);
|
||||
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
|
||||
newXS(strcpy(buf, "we"), XS__we, file);
|
||||
|
||||
+11
-10
@@ -173,25 +173,27 @@ void Embperl::DoInit() {
|
||||
Log.Out(Logs::General, Logs::Quests, "Loading perlemb plugins.");
|
||||
try
|
||||
{
|
||||
eval_pv("main::eval_file('plugin', 'plugin.pl');", FALSE);
|
||||
std::string perl_command;
|
||||
perl_command = "main::eval_file('plugin', '" + Config->PluginPlFile + "');";
|
||||
eval_pv(perl_command.c_str(), FALSE);
|
||||
}
|
||||
catch(const char *err)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Quests, "Warning - plugin.pl: %s", err);
|
||||
Log.Out(Logs::General, Logs::Quests, "Warning - %s: %s", Config->PluginPlFile.c_str(), err);
|
||||
}
|
||||
try
|
||||
{
|
||||
//should probably read the directory in c, instead, so that
|
||||
//I can echo filenames as I do it, but c'mon... I'm lazy and this 1 line reads in all the plugins
|
||||
eval_pv(
|
||||
"if(opendir(D,'plugins')) { "
|
||||
std::string perl_command =
|
||||
"if(opendir(D,'" + Config->PluginDir +"')) { "
|
||||
" my @d = readdir(D);"
|
||||
" closedir(D);"
|
||||
" foreach(@d){ "
|
||||
" main::eval_file('plugin','plugins/'.$_)if/\\.pl$/;"
|
||||
" main::eval_file('plugin','" + Config->PluginDir + "/'.$_)if/\\.pl$/;"
|
||||
" }"
|
||||
"}"
|
||||
,FALSE);
|
||||
"}";
|
||||
eval_pv(perl_command.c_str(),FALSE);
|
||||
}
|
||||
catch(const char *err)
|
||||
{
|
||||
@@ -276,10 +278,9 @@ int Embperl::dosub(const char * subname, const std::vector<std::string> * args,
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
PUSHMARK(SP);
|
||||
if(args && args->size())
|
||||
if(args && !args->empty())
|
||||
{
|
||||
for(std::vector<std::string>::const_iterator i = args->begin(); i != args->end(); ++i)
|
||||
{
|
||||
for (auto i = args->begin(); i != args->end(); ++i) {
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), i->length())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ Eglin
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "zone_config.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@@ -52,11 +54,23 @@ extern "C" { //the perl headers dont do this for us...
|
||||
#ifdef Zero
|
||||
#undef Zero
|
||||
#endif
|
||||
//These need to be cleaned up on FreeBSD
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#ifdef do_open
|
||||
#undef do_open
|
||||
#endif
|
||||
|
||||
#ifdef do_close
|
||||
#undef do_close
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//so embedded scripts can use xs extensions (ala 'use socket;')
|
||||
EXTERN_C void boot_DynaLoader(pTHX_ CV* cv);
|
||||
EXTERN_C void xs_init(pTHX);
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
class Embperl
|
||||
{
|
||||
private:
|
||||
|
||||
+18
-14
@@ -1,26 +1,30 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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
|
||||
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
|
||||
*/
|
||||
|
||||
#ifdef EMBPERL
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "masterentity.h"
|
||||
#include "command.h"
|
||||
#ifdef BOTS
|
||||
#include "bot_command.h"
|
||||
#endif
|
||||
|
||||
#include "embperl.h"
|
||||
#include "embxs.h"
|
||||
@@ -29,7 +33,7 @@
|
||||
|
||||
const char *getItemName(unsigned itemid)
|
||||
{
|
||||
const Item_Struct* item = nullptr;
|
||||
const EQEmu::ItemBase* item = nullptr;
|
||||
item = database.GetItem(itemid);
|
||||
|
||||
if (item)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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
|
||||
*/
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if (!defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1900))
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
#include "../common/races.h"
|
||||
#include "encounter.h"
|
||||
#include "entity.h"
|
||||
#include "mob.h"
|
||||
|
||||
class Zone;
|
||||
|
||||
Encounter::Encounter(const char* enc_name)
|
||||
:Mob
|
||||
(
|
||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, glm::vec4(0,0,0,0), 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
)
|
||||
{
|
||||
encounter_name[0] = 0;
|
||||
strn0cpy(encounter_name, enc_name, 64);
|
||||
remove_me = false;
|
||||
}
|
||||
|
||||
Encounter::~Encounter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Encounter::Process() {
|
||||
if (remove_me) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 ENCOUNTER_H
|
||||
#define ENCOUNTER_H
|
||||
|
||||
#include "mob.h"
|
||||
#include "../common/types.h"
|
||||
#include "../common/timer.h"
|
||||
|
||||
class Group;
|
||||
class Raid;
|
||||
struct ExtraAttackOptions;
|
||||
|
||||
class Encounter : public Mob
|
||||
{
|
||||
public:
|
||||
Encounter(const char* enc_name);
|
||||
~Encounter();
|
||||
|
||||
//abstract virtual function implementations required by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0) {
|
||||
return false;
|
||||
}
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
virtual Group* GetGroup() { return 0; }
|
||||
|
||||
bool IsEncounter() const { return true; }
|
||||
const char* GetEncounterName() const { return encounter_name; }
|
||||
|
||||
bool Process();
|
||||
virtual void Depop(bool not_used = true) { remove_me = true; }
|
||||
|
||||
|
||||
protected:
|
||||
bool remove_me;
|
||||
char encounter_name[64];
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
+254
-121
@@ -54,14 +54,13 @@
|
||||
#endif
|
||||
|
||||
extern Zone *zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern NetConnection net;
|
||||
extern uint32 numclients;
|
||||
extern PetitionList petition_list;
|
||||
|
||||
extern char errorname[32];
|
||||
extern uint16 adverrornum;
|
||||
|
||||
Entity::Entity()
|
||||
{
|
||||
@@ -82,7 +81,7 @@ Client *Entity::CastToClient()
|
||||
}
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsClient()) {
|
||||
Log.Out(Logs::General, Logs::Error, "CastToClient error (not client)");
|
||||
Log.Out(Logs::General, Logs::Error, "CastToClient error (not client)");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -176,6 +175,11 @@ Beacon *Entity::CastToBeacon()
|
||||
return static_cast<Beacon *>(this);
|
||||
}
|
||||
|
||||
Encounter *Entity::CastToEncounter()
|
||||
{
|
||||
return static_cast<Encounter *>(this);
|
||||
}
|
||||
|
||||
const Client *Entity::CastToClient() const
|
||||
{
|
||||
if (this == 0x00) {
|
||||
@@ -266,6 +270,11 @@ const Beacon* Entity::CastToBeacon() const
|
||||
return static_cast<const Beacon *>(this);
|
||||
}
|
||||
|
||||
const Encounter* Entity::CastToEncounter() const
|
||||
{
|
||||
return static_cast<const Encounter *>(this);
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
Bot *Entity::CastToBot()
|
||||
{
|
||||
@@ -462,17 +471,27 @@ void EntityList::CorpseProcess()
|
||||
|
||||
void EntityList::MobProcess()
|
||||
{
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
if (numclients < 1)
|
||||
return;
|
||||
#endif
|
||||
bool mob_dead;
|
||||
|
||||
auto it = mob_list.begin();
|
||||
while (it != mob_list.end()) {
|
||||
uint16 id = it->first;
|
||||
Mob *mob = it->second;
|
||||
|
||||
size_t sz = mob_list.size();
|
||||
bool p_val = mob->Process();
|
||||
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
// spawn_events can cause spawns and deaths while zone empty.
|
||||
// At the very least, process that.
|
||||
if (numclients < 1) {
|
||||
mob_dead = mob->CastToNPC()->GetDepop();
|
||||
}
|
||||
else {
|
||||
mob_dead = !mob->Process();
|
||||
}
|
||||
#else
|
||||
mob_dead = !mob->Process();
|
||||
#endif
|
||||
size_t a_sz = mob_list.size();
|
||||
|
||||
if(a_sz > sz) {
|
||||
@@ -485,7 +504,7 @@ void EntityList::MobProcess()
|
||||
++it;
|
||||
}
|
||||
|
||||
if(!p_val) {
|
||||
if(mob_dead) {
|
||||
if(mob->IsNPC()) {
|
||||
entity_list.RemoveNPC(id);
|
||||
}
|
||||
@@ -536,6 +555,21 @@ void EntityList::BeaconProcess()
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::EncounterProcess()
|
||||
{
|
||||
auto it = encounter_list.begin();
|
||||
while (it != encounter_list.end()) {
|
||||
if (!it->second->Process()) {
|
||||
safe_delete(it->second);
|
||||
free_ids.push(it->first);
|
||||
it = encounter_list.erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::AddGroup(Group *group)
|
||||
{
|
||||
if (group == nullptr) //this seems to be happening somehow...
|
||||
@@ -543,7 +577,7 @@ void EntityList::AddGroup(Group *group)
|
||||
|
||||
uint32 gid = worldserver.NextGroupID();
|
||||
if (gid == 0) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
"Unable to get new group ID from world server. group is going to be broken.");
|
||||
return;
|
||||
}
|
||||
@@ -572,7 +606,7 @@ void EntityList::AddRaid(Raid *raid)
|
||||
|
||||
uint32 gid = worldserver.NextGroupID();
|
||||
if (gid == 0) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
"Unable to get new group ID from world server. group is going to be broken.");
|
||||
return;
|
||||
}
|
||||
@@ -610,6 +644,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
||||
{
|
||||
npc->SetID(GetFreeID());
|
||||
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
|
||||
|
||||
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
||||
|
||||
/* Web Interface: NPC Spawn (Pop) */
|
||||
@@ -631,15 +666,17 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
||||
uint16 emoteid = npc->GetEmoteID();
|
||||
if (emoteid != 0)
|
||||
npc->DoNPCEmote(ONSPAWN, emoteid);
|
||||
|
||||
npc->SetSpawned();
|
||||
if (SendSpawnPacket) {
|
||||
if (dontqueue) { // aka, SEND IT NOW BITCH!
|
||||
EQApplicationPacket *app = new EQApplicationPacket;
|
||||
auto app = new EQApplicationPacket;
|
||||
npc->CreateSpawnPacket(app, npc);
|
||||
QueueClients(npc, app);
|
||||
npc->SendArmorAppearance();
|
||||
npc->SetAppearance(npc->GetGuardPointAnim(),false);
|
||||
safe_delete(app);
|
||||
} else {
|
||||
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
||||
auto ns = new NewSpawn_Struct;
|
||||
memset(ns, 0, sizeof(NewSpawn_Struct));
|
||||
npc->FillSpawnStruct(ns, nullptr); // Not working on player newspawns, so it's safe to use a ForWho of 0
|
||||
AddToSpawnQueue(npc->GetID(), &ns);
|
||||
@@ -651,6 +688,16 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
||||
|
||||
npc_list.insert(std::pair<uint16, NPC *>(npc->GetID(), npc));
|
||||
mob_list.insert(std::pair<uint16, Mob *>(npc->GetID(), npc));
|
||||
|
||||
/* Zone controller process EVENT_SPAWN_ZONE */
|
||||
if (RuleB(Zone, UseZoneController)) {
|
||||
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||
char data_pass[100] = { 0 };
|
||||
snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID());
|
||||
parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue)
|
||||
@@ -658,19 +705,19 @@ void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue)
|
||||
if (merc)
|
||||
{
|
||||
merc->SetID(GetFreeID());
|
||||
|
||||
merc->SetSpawned();
|
||||
if (SendSpawnPacket)
|
||||
{
|
||||
if (dontqueue) {
|
||||
// Send immediately
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket();
|
||||
auto outapp = new EQApplicationPacket();
|
||||
merc->CreateSpawnPacket(outapp);
|
||||
outapp->priority = 6;
|
||||
QueueClients(merc, outapp, true);
|
||||
safe_delete(outapp);
|
||||
} else {
|
||||
// Queue the packet
|
||||
NewSpawn_Struct *ns = new NewSpawn_Struct;
|
||||
auto ns = new NewSpawn_Struct;
|
||||
memset(ns, 0, sizeof(NewSpawn_Struct));
|
||||
merc->FillSpawnStruct(ns, 0);
|
||||
AddToSpawnQueue(merc->GetID(), &ns);
|
||||
@@ -725,6 +772,12 @@ void EntityList::AddBeacon(Beacon *beacon)
|
||||
beacon_list.insert(std::pair<uint16, Beacon *>(beacon->GetID(), beacon));
|
||||
}
|
||||
|
||||
void EntityList::AddEncounter(Encounter *encounter)
|
||||
{
|
||||
encounter->SetID(GetFreeID());
|
||||
encounter_list.insert(std::pair<uint16, Encounter *>(encounter->GetID(), encounter));
|
||||
}
|
||||
|
||||
void EntityList::AddToSpawnQueue(uint16 entityid, NewSpawn_Struct **ns)
|
||||
{
|
||||
uint32 count;
|
||||
@@ -745,10 +798,23 @@ void EntityList::CheckSpawnQueue()
|
||||
EQApplicationPacket *outapp = 0;
|
||||
|
||||
iterator.Reset();
|
||||
NewSpawn_Struct *ns;
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
outapp = new EQApplicationPacket;
|
||||
Mob::CreateSpawnPacket(outapp, iterator.GetData());
|
||||
ns = iterator.GetData();
|
||||
Mob::CreateSpawnPacket(outapp, ns);
|
||||
QueueClients(0, outapp);
|
||||
auto it = npc_list.find(ns->spawn.spawnId);
|
||||
if (it == npc_list.end()) {
|
||||
// We must of despawned, hope that's the reason!
|
||||
Log.Out(Logs::General, Logs::Error, "Error in EntityList::CheckSpawnQueue: Unable to find NPC for spawnId '%u'", ns->spawn.spawnId);
|
||||
}
|
||||
else {
|
||||
NPC *pnpc = it->second;
|
||||
pnpc->SendArmorAppearance();
|
||||
pnpc->SetAppearance(pnpc->GetGuardPointAnim(), false);
|
||||
}
|
||||
safe_delete(outapp);
|
||||
iterator.RemoveCurrent();
|
||||
}
|
||||
@@ -820,7 +886,7 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
|
||||
if (door_list.empty())
|
||||
return false;
|
||||
|
||||
uint32 mask_test = client->GetClientVersionBit();
|
||||
uint32 mask_test = client->ClientVersionBit();
|
||||
int count = 0;
|
||||
|
||||
auto it = door_list.begin();
|
||||
@@ -835,7 +901,7 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
|
||||
return false;
|
||||
|
||||
uint32 length = count * sizeof(Door_Struct);
|
||||
uchar *packet_buffer = new uchar[length];
|
||||
auto packet_buffer = new uchar[length];
|
||||
memset(packet_buffer, 0, length);
|
||||
uchar *ptr = packet_buffer;
|
||||
Doors *door;
|
||||
@@ -876,12 +942,18 @@ bool EntityList::MakeDoorSpawnPacket(EQApplicationPacket *app, Client *client)
|
||||
|
||||
Entity *EntityList::GetEntityMob(uint16 id)
|
||||
{
|
||||
return mob_list.count(id) ? mob_list.at(id) : nullptr;
|
||||
auto it = mob_list.find(id);
|
||||
if (it != mob_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityMerc(uint16 id)
|
||||
{
|
||||
return merc_list.count(id) ? merc_list.at(id) : nullptr;
|
||||
auto it = merc_list.find(id);
|
||||
if (it != merc_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityMob(const char *name)
|
||||
@@ -901,12 +973,18 @@ Entity *EntityList::GetEntityMob(const char *name)
|
||||
|
||||
Entity *EntityList::GetEntityDoor(uint16 id)
|
||||
{
|
||||
return door_list.count(id) ? door_list.at(id) : nullptr;
|
||||
auto it = door_list.find(id);
|
||||
if (it != door_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityCorpse(uint16 id)
|
||||
{
|
||||
return corpse_list.count(id) ? corpse_list.at(id) : nullptr;
|
||||
auto it = corpse_list.find(id);
|
||||
if (it != corpse_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityCorpse(const char *name)
|
||||
@@ -926,17 +1004,34 @@ Entity *EntityList::GetEntityCorpse(const char *name)
|
||||
|
||||
Entity *EntityList::GetEntityTrap(uint16 id)
|
||||
{
|
||||
return trap_list.count(id) ? trap_list.at(id) : nullptr;
|
||||
auto it = trap_list.find(id);
|
||||
if (it != trap_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityObject(uint16 id)
|
||||
{
|
||||
return object_list.count(id) ? object_list.at(id) : nullptr;
|
||||
auto it = object_list.find(id);
|
||||
if (it != object_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityBeacon(uint16 id)
|
||||
{
|
||||
return beacon_list.count(id) ? beacon_list.at(id) : nullptr;
|
||||
auto it = beacon_list.find(id);
|
||||
if (it != beacon_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetEntityEncounter(uint16 id)
|
||||
{
|
||||
auto it = encounter_list.find(id);
|
||||
if (it != encounter_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Entity *EntityList::GetID(uint16 get_id)
|
||||
@@ -954,6 +1049,8 @@ Entity *EntityList::GetID(uint16 get_id)
|
||||
return ent;
|
||||
else if ((ent=entity_list.GetEntityBeacon(get_id)) != 0)
|
||||
return ent;
|
||||
else if ((ent = entity_list.GetEntityEncounter(get_id)) != 0)
|
||||
return ent;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -1130,6 +1227,8 @@ void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language,
|
||||
|
||||
void EntityList::ChannelMessageSend(Mob *to, uint8 chan_num, uint8 language, const char *message, ...)
|
||||
{
|
||||
if (!to->IsClient())
|
||||
return;
|
||||
va_list argptr;
|
||||
char buffer[4096];
|
||||
|
||||
@@ -1137,8 +1236,7 @@ void EntityList::ChannelMessageSend(Mob *to, uint8 chan_num, uint8 language, con
|
||||
vsnprintf(buffer, 4096, message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if (client_list.count(to->GetID()))
|
||||
client_list.at(to->GetID())->ChannelMessageSend(0, 0, chan_num, language, buffer);
|
||||
to->CastToClient()->ChannelMessageSend(0, 0, chan_num, language, buffer);
|
||||
}
|
||||
|
||||
void EntityList::SendZoneSpawns(Client *client)
|
||||
@@ -1168,19 +1266,64 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
|
||||
NewSpawn_Struct ns;
|
||||
Mob *spawn;
|
||||
uint32 maxspawns = 100;
|
||||
EQApplicationPacket *app;
|
||||
|
||||
if (maxspawns > mob_list.size())
|
||||
maxspawns = mob_list.size();
|
||||
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
||||
auto bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
||||
|
||||
bool delaypkt = false;
|
||||
const glm::vec4& cpos = client->GetPosition();
|
||||
const float dmax = 600.0 * 600.0;
|
||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
||||
spawn = it->second;
|
||||
if (spawn && spawn->InZone()) {
|
||||
if (spawn && spawn->GetID() > 0 && spawn->Spawned()) {
|
||||
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
|
||||
spawn->CastToClient()->IsHoveringForRespawn()))
|
||||
continue;
|
||||
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
||||
spawn->FillSpawnStruct(&ns, client);
|
||||
bzsp->AddSpawn(&ns);
|
||||
|
||||
#if 1
|
||||
const glm::vec4& spos = spawn->GetPosition();
|
||||
|
||||
delaypkt = false;
|
||||
if (DistanceSquared(cpos, spos) > dmax || (spawn->IsClient() && (spawn->GetRace() == MINOR_ILL_OBJ || spawn->GetRace() == TREE)))
|
||||
delaypkt = true;
|
||||
|
||||
if (delaypkt) {
|
||||
app = new EQApplicationPacket;
|
||||
spawn->CreateSpawnPacket(app);
|
||||
client->QueuePacket(app, true, Client::CLIENT_CONNECTED);
|
||||
safe_delete(app);
|
||||
}
|
||||
else {
|
||||
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
||||
spawn->FillSpawnStruct(&ns, client);
|
||||
bzsp->AddSpawn(&ns);
|
||||
}
|
||||
|
||||
spawn->SendArmorAppearance(client);
|
||||
#else
|
||||
/* original code kept for spawn packet research */
|
||||
int32 race = spawn->GetRace();
|
||||
|
||||
// Illusion races on PCs don't work as a mass spawn
|
||||
// But they will work as an add_spawn AFTER CLIENT_CONNECTED.
|
||||
if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) {
|
||||
app = new EQApplicationPacket;
|
||||
spawn->CreateSpawnPacket(app);
|
||||
client->QueuePacket(app, true, Client::CLIENT_CONNECTED);
|
||||
safe_delete(app);
|
||||
}
|
||||
else {
|
||||
memset(&ns, 0, sizeof(NewSpawn_Struct));
|
||||
spawn->FillSpawnStruct(&ns, client);
|
||||
bzsp->AddSpawn(&ns);
|
||||
}
|
||||
|
||||
// Despite being sent in the OP_ZoneSpawns packet, the client
|
||||
// does not display worn armor correctly so display it.
|
||||
spawn->SendArmorAppearance(client);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
safe_delete(bzsp);
|
||||
@@ -1217,7 +1360,7 @@ void EntityList::SendZoneCorpsesBulk(Client *client)
|
||||
Corpse *spawn;
|
||||
uint32 maxspawns = 100;
|
||||
|
||||
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
||||
auto bzsp = new BulkZoneSpawnPacket(client, maxspawns);
|
||||
|
||||
for (auto it = corpse_list.begin(); it != corpse_list.end(); ++it) {
|
||||
spawn = it->second;
|
||||
@@ -1234,7 +1377,7 @@ void EntityList::SendZoneObjects(Client *client)
|
||||
{
|
||||
auto it = object_list.begin();
|
||||
while (it != object_list.end()) {
|
||||
EQApplicationPacket *app = new EQApplicationPacket;
|
||||
auto app = new EQApplicationPacket;
|
||||
it->second->CreateSpawnPacket(app);
|
||||
client->FastQueuePacket(&app);
|
||||
++it;
|
||||
@@ -1320,7 +1463,7 @@ void EntityList::RefreshAutoXTargets(Client *c)
|
||||
continue;
|
||||
|
||||
if (m->CheckAggro(c) && !c->IsXTarget(m)) {
|
||||
c->AddAutoXTarget(m);
|
||||
c->AddAutoXTarget(m, false); // we only call this before a bulk, so lets not send right away
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1374,7 +1517,9 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
|
||||
if (c != sender) {
|
||||
if (Target == sender) {
|
||||
if (inspect_buffs) { // if inspect_buffs is true we're sending a mob's buffs to those with the LAA
|
||||
if (c->IsRaidGrouped()) {
|
||||
if (c->GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs)) {
|
||||
Send = true;
|
||||
} else if (c->IsRaidGrouped()) {
|
||||
Raid *raid = c->GetRaid();
|
||||
if (!raid)
|
||||
continue;
|
||||
@@ -1398,7 +1543,7 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
|
||||
}
|
||||
}
|
||||
|
||||
if (Send && (c->GetClientVersionBit() & ClientVersionBits))
|
||||
if (Send && (c->ClientVersionBit() & ClientVersionBits))
|
||||
c->QueuePacket(app, ackreq);
|
||||
}
|
||||
}
|
||||
@@ -1873,13 +2018,13 @@ void EntityList::QueueClientsGuild(Mob *sender, const EQApplicationPacket *app,
|
||||
|
||||
void EntityList::QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struct *gbius, uint32 GuildID)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankItemUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankItemUpdate_Struct));
|
||||
|
||||
GuildBankItemUpdate_Struct *outgbius = (GuildBankItemUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
memcpy(outgbius, gbius, sizeof(GuildBankItemUpdate_Struct));
|
||||
|
||||
const Item_Struct *Item = database.GetItem(gbius->ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(gbius->ItemID);
|
||||
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
@@ -2056,7 +2201,7 @@ void EntityList::RemoveAllDoors()
|
||||
|
||||
void EntityList::DespawnAllDoors()
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_RemoveAllDoors, 0);
|
||||
auto outapp = new EQApplicationPacket(OP_RemoveAllDoors, 0);
|
||||
this->QueueClients(0,outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@@ -2066,7 +2211,7 @@ void EntityList::RespawnAllDoors()
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
if (it->second) {
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket();
|
||||
auto outapp = new EQApplicationPacket();
|
||||
MakeDoorSpawnPacket(outapp, it->second);
|
||||
it->second->FastQueuePacket(&outapp);
|
||||
}
|
||||
@@ -2285,7 +2430,7 @@ void EntityList::Clear()
|
||||
|
||||
void EntityList::UpdateWho(bool iSendFullUpdate)
|
||||
{
|
||||
if ((!worldserver.Connected()) || !ZoneLoaded)
|
||||
if ((!worldserver.Connected()) || !is_zone_loaded)
|
||||
return;
|
||||
uint32 tmpNumUpdates = numclients + 5;
|
||||
ServerPacket* pack = 0;
|
||||
@@ -2383,12 +2528,14 @@ void EntityList::Depop(bool StartSpawnTimer)
|
||||
if (pnpc->IsFindable())
|
||||
UpdateFindableNPCState(pnpc, true);
|
||||
|
||||
pnpc->WipeHateList();
|
||||
|
||||
pnpc->Depop(StartSpawnTimer);
|
||||
|
||||
/* Web Interface Depop Entities */
|
||||
std::vector<std::string> params;
|
||||
params.push_back(std::to_string((long)pnpc->GetID()));
|
||||
RemoteCallSubscriptionHandler::Instance()->OnEvent("NPC.Depop", params);
|
||||
|
||||
pnpc->Depop(StartSpawnTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2564,7 +2711,7 @@ void EntityList::ListNPCs(Client* client, const char *arg1, const char *arg2, ui
|
||||
}
|
||||
} else if (searchtype == 1) {
|
||||
client->Message(0, "Searching by name method. (%s)",arg1);
|
||||
char* tmp = new char[strlen(arg1) + 1];
|
||||
auto tmp = new char[strlen(arg1) + 1];
|
||||
strcpy(tmp, arg1);
|
||||
strupr(tmp);
|
||||
while (it != npc_list.end()) {
|
||||
@@ -2635,7 +2782,7 @@ void EntityList::FindPathsToAllNPCs()
|
||||
glm::vec3 Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
|
||||
glm::vec3 Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
|
||||
std::deque<int> Route = zone->pathing->FindRoute(Node0, Dest);
|
||||
if (Route.size() == 0)
|
||||
if (Route.empty())
|
||||
printf("Unable to find a route to %s\n", it->second->GetName());
|
||||
else
|
||||
printf("Found a route to %s\n", it->second->GetName());
|
||||
@@ -2679,7 +2826,7 @@ int32 EntityList::DeletePlayerCorpses()
|
||||
|
||||
void EntityList::SendPetitionToAdmins()
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PetitionUpdate,sizeof(PetitionUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_PetitionUpdate, sizeof(PetitionUpdate_Struct));
|
||||
PetitionUpdate_Struct *pcus = (PetitionUpdate_Struct*) outapp->pBuffer;
|
||||
pcus->petnumber = 0; // Petition Number
|
||||
pcus->color = 0;
|
||||
@@ -2699,7 +2846,7 @@ void EntityList::SendPetitionToAdmins()
|
||||
|
||||
void EntityList::SendPetitionToAdmins(Petition *pet)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PetitionUpdate,sizeof(PetitionUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_PetitionUpdate, sizeof(PetitionUpdate_Struct));
|
||||
PetitionUpdate_Struct *pcus = (PetitionUpdate_Struct*) outapp->pBuffer;
|
||||
pcus->petnumber = pet->GetID(); // Petition Number
|
||||
if (pet->CheckedOut()) {
|
||||
@@ -2732,7 +2879,7 @@ void EntityList::SendPetitionToAdmins(Petition *pet)
|
||||
|
||||
void EntityList::ClearClientPetitionQueue()
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PetitionUpdate,sizeof(PetitionUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_PetitionUpdate, sizeof(PetitionUpdate_Struct));
|
||||
PetitionUpdate_Struct *pet = (PetitionUpdate_Struct*) outapp->pBuffer;
|
||||
pet->color = 0x00;
|
||||
pet->status = 0xFFFFFFFF;
|
||||
@@ -2800,7 +2947,7 @@ void BulkZoneSpawnPacket::SendBuffer()
|
||||
return;
|
||||
|
||||
uint32 tmpBufSize = (index * sizeof(NewSpawn_Struct));
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZoneSpawns, (unsigned char *)data, tmpBufSize);
|
||||
auto outapp = new EQApplicationPacket(OP_ZoneSpawns, (unsigned char *)data, tmpBufSize);
|
||||
|
||||
if (pSendTo) {
|
||||
pSendTo->FastQueuePacket(&outapp);
|
||||
@@ -2941,11 +3088,11 @@ bool EntityList::MakeTrackPacket(Client *client)
|
||||
float MobDistance;
|
||||
|
||||
if (client->GetClass() == DRUID)
|
||||
distance = (client->GetSkill(SkillTracking) * 10);
|
||||
distance = (client->GetSkill(EQEmu::skills::SkillTracking) * 10);
|
||||
else if (client->GetClass() == RANGER)
|
||||
distance = (client->GetSkill(SkillTracking) * 12);
|
||||
distance = (client->GetSkill(EQEmu::skills::SkillTracking) * 12);
|
||||
else if (client->GetClass() == BARD)
|
||||
distance = (client->GetSkill(SkillTracking) * 7);
|
||||
distance = (client->GetSkill(EQEmu::skills::SkillTracking) * 7);
|
||||
if (distance <= 0)
|
||||
return false;
|
||||
if (distance < 300)
|
||||
@@ -2967,7 +3114,7 @@ bool EntityList::MakeTrackPacket(Client *client)
|
||||
[](const std::pair<Mob *, float> &a, const std::pair<Mob *, float> &b) {
|
||||
return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp();
|
||||
});
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_Track, sizeof(Track_Struct) * tracking_list.size());
|
||||
auto outapp = new EQApplicationPacket(OP_Track, sizeof(Track_Struct) * tracking_list.size());
|
||||
Tracking_Struct *outtrack = (Tracking_Struct *)outapp->pBuffer;
|
||||
outapp->priority = 6;
|
||||
|
||||
@@ -3024,56 +3171,24 @@ bool EntityList::Fighting(Mob *targ)
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntityList::AddHealAggro(Mob *target, Mob *caster, uint16 thedam)
|
||||
void EntityList::AddHealAggro(Mob *target, Mob *caster, uint16 hate)
|
||||
{
|
||||
NPC *cur = nullptr;
|
||||
uint16 count = 0;
|
||||
std::list<NPC *> npc_sub_list;
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
cur = it->second;
|
||||
if (hate == 0)
|
||||
return;
|
||||
|
||||
if (!cur->CheckAggro(target)) {
|
||||
++it;
|
||||
for (auto &e : npc_list) {
|
||||
auto &npc = e.second;
|
||||
if (!npc->CheckAggro(target) || npc->IsFeared())
|
||||
continue;
|
||||
}
|
||||
if (!cur->IsMezzed() && !cur->IsStunned() && !cur->IsFeared()) {
|
||||
npc_sub_list.push_back(cur);
|
||||
++count;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
if (zone->random.Roll(50)) // witness check -- place holder
|
||||
// This is either a level check (con color check?) or a stat roll
|
||||
continue;
|
||||
|
||||
if (thedam > 1) {
|
||||
if (count > 0)
|
||||
thedam /= count;
|
||||
|
||||
if (thedam < 1)
|
||||
thedam = 1;
|
||||
}
|
||||
|
||||
cur = nullptr;
|
||||
auto sit = npc_sub_list.begin();
|
||||
while (sit != npc_sub_list.end()) {
|
||||
cur = *sit;
|
||||
|
||||
if (cur->IsPet()) {
|
||||
if (caster) {
|
||||
if (cur->CheckAggro(caster)) {
|
||||
cur->AddToHateList(caster, thedam);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (caster) {
|
||||
if (cur->CheckAggro(caster)) {
|
||||
cur->AddToHateList(caster, thedam);
|
||||
} else {
|
||||
cur->AddToHateList(caster, thedam * 0.33);
|
||||
}
|
||||
}
|
||||
}
|
||||
++sit;
|
||||
if ((npc->IsMezzed() || npc->IsStunned()) && hate > 4) // patch notes say stunned/mezzed NPCs get a fraction of the hate
|
||||
npc->AddToHateList(caster, hate / 4); // made up number
|
||||
else
|
||||
npc->AddToHateList(caster, hate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3419,6 +3534,15 @@ bool EntityList::IsMobInZone(Mob *who)
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
auto enc_it = encounter_list.begin();
|
||||
while (enc_it != encounter_list.end()) {
|
||||
if (enc_it->second == who) {
|
||||
return true;
|
||||
}
|
||||
++enc_it;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3642,7 +3766,7 @@ void EntityList::QuestJournalledSayClose(Mob *sender, Client *QuestInitiator,
|
||||
|
||||
// Send the message to the quest initiator such that the client will enter it into the NPC Quest Journal
|
||||
if (QuestInitiator) {
|
||||
char *buf = new char[strlen(mobname) + strlen(message) + 10];
|
||||
auto buf = new char[strlen(mobname) + strlen(message) + 10];
|
||||
sprintf(buf, "%s says, '%s'", mobname, message);
|
||||
QuestInitiator->QuestJournalledMessage(mobname, buf);
|
||||
safe_delete_array(buf);
|
||||
@@ -3712,7 +3836,7 @@ void EntityList::SendGroupLeave(uint32 gid, const char *name)
|
||||
g = c->GetGroup();
|
||||
if (g) {
|
||||
if (g->GetID() == gid) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
strcpy(gj->membername, name);
|
||||
gj->action = groupActLeave;
|
||||
@@ -3741,7 +3865,7 @@ void EntityList::SendGroupJoin(uint32 gid, const char *name)
|
||||
g = it->second->GetGroup();
|
||||
if (g) {
|
||||
if (g->GetID() == gid) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
strcpy(gj->membername, name);
|
||||
gj->action = groupActJoin;
|
||||
@@ -3777,15 +3901,15 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
|
||||
|
||||
uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time)
|
||||
{
|
||||
const Item_Struct *is = database.GetItem(itemid);
|
||||
const EQEmu::ItemBase *is = database.GetItem(itemid);
|
||||
if (!is)
|
||||
return 0;
|
||||
|
||||
ItemInst *i = new ItemInst(is, is->MaxCharges);
|
||||
auto i = new ItemInst(is, is->MaxCharges);
|
||||
if (!i)
|
||||
return 0;
|
||||
|
||||
Object *object = new Object(i, position.x, position.y, position.z, position.w,decay_time);
|
||||
auto object = new Object(i, position.x, position.y, position.z, position.w, decay_time);
|
||||
entity_list.AddObject(object, true);
|
||||
|
||||
safe_delete(i);
|
||||
@@ -3800,7 +3924,7 @@ uint16 EntityList::CreateGroundObjectFromModel(const char *model, const glm::vec
|
||||
if (!model)
|
||||
return 0;
|
||||
|
||||
Object *object = new Object(model, position.x, position.y, position.z, position.w, type);
|
||||
auto object = new Object(model, position.x, position.y, position.z, position.w, type);
|
||||
entity_list.AddObject(object, true);
|
||||
|
||||
if (!object)
|
||||
@@ -3814,7 +3938,7 @@ uint16 EntityList::CreateDoor(const char *model, const glm::vec4& position, uint
|
||||
if (!model)
|
||||
return 0; // fell through everything, this is bad/incomplete from perl
|
||||
|
||||
Doors *door = new Doors(model, position, opentype, size);
|
||||
auto door = new Doors(model, position, opentype, size);
|
||||
RemoveAllDoors();
|
||||
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
|
||||
entity_list.AddDoor(door);
|
||||
@@ -3989,7 +4113,7 @@ void EntityList::ZoneWho(Client *c, Who_All_Struct *Who)
|
||||
}
|
||||
|
||||
PacketLength = PacketLength + sizeof(WhoAllReturnStruct) + (47 * Entries);
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_WhoAllResponse, PacketLength);
|
||||
auto outapp = new EQApplicationPacket(OP_WhoAllResponse, PacketLength);
|
||||
char *Buffer = (char *)outapp->pBuffer;
|
||||
WhoAllReturnStruct *WARS = (WhoAllReturnStruct *)Buffer;
|
||||
WARS->id = 0;
|
||||
@@ -4175,7 +4299,7 @@ uint16 EntityList::GetClientCount(){
|
||||
uint16 ClientCount = 0;
|
||||
std::list<Client*> client_list;
|
||||
entity_list.GetClientList(client_list);
|
||||
std::list<Client*>::iterator iter = client_list.begin();
|
||||
auto iter = client_list.begin();
|
||||
while (iter != client_list.end()) {
|
||||
Client *entry = (*iter);
|
||||
entry->GetCleanName();
|
||||
@@ -4309,7 +4433,7 @@ void EntityList::SendFindableNPCList(Client *c)
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct));
|
||||
|
||||
FindableNPC_Struct *fnpcs = (FindableNPC_Struct *)outapp->pBuffer;
|
||||
|
||||
@@ -4344,7 +4468,7 @@ void EntityList::UpdateFindableNPCState(NPC *n, bool Remove)
|
||||
if (!n || !n->IsFindable())
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_SendFindableNPCs, sizeof(FindableNPC_Struct));
|
||||
|
||||
FindableNPC_Struct *fnpcs = (FindableNPC_Struct *)outapp->pBuffer;
|
||||
|
||||
@@ -4362,7 +4486,7 @@ void EntityList::UpdateFindableNPCState(NPC *n, bool Remove)
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
Client *c = it->second;
|
||||
if (c && (c->GetClientVersion() >= ClientVersion::SoD))
|
||||
if (c && (c->ClientVersion() >= EQEmu::versions::ClientVersion::SoD))
|
||||
c->QueuePacket(outapp);
|
||||
|
||||
++it;
|
||||
@@ -4435,9 +4559,9 @@ void EntityList::AddLootToNPCS(uint32 item_id, uint32 count)
|
||||
if (npc_count == 0)
|
||||
return;
|
||||
|
||||
NPC **npcs = new NPC*[npc_count];
|
||||
int *counts = new int[npc_count];
|
||||
bool *marked = new bool[npc_count];
|
||||
auto npcs = new NPC *[npc_count];
|
||||
auto counts = new int[npc_count];
|
||||
auto marked = new bool[npc_count];
|
||||
memset(counts, 0, sizeof(int) * npc_count);
|
||||
memset(marked, 0, sizeof(bool) * npc_count);
|
||||
|
||||
@@ -4459,7 +4583,7 @@ void EntityList::AddLootToNPCS(uint32 item_id, uint32 count)
|
||||
for (int j = 0; j < npc_count; ++j)
|
||||
selection.push_back(j);
|
||||
|
||||
while (selection.size() > 0 && count > 0) {
|
||||
while (!selection.empty() && count > 0) {
|
||||
int k = zone->random.Int(0, selection.size() - 1);
|
||||
counts[selection[k]]++;
|
||||
count--;
|
||||
@@ -4479,7 +4603,7 @@ void EntityList::AddLootToNPCS(uint32 item_id, uint32 count)
|
||||
|
||||
void EntityList::CameraEffect(uint32 duration, uint32 intensity)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CameraEffect, sizeof(Camera_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_CameraEffect, sizeof(Camera_Struct));
|
||||
Camera_Struct* cs = (Camera_Struct*) outapp->pBuffer;
|
||||
cs->duration = duration; // Duration in milliseconds
|
||||
cs->intensity = ((intensity * 6710886) + 1023410176); // Intensity ranges from 1023410176 to 1090519040, so simplify it from 0 to 10.
|
||||
@@ -4513,7 +4637,7 @@ NPC *EntityList::GetClosestBanker(Mob *sender, uint32 &distance)
|
||||
|
||||
void EntityList::ExpeditionWarning(uint32 minutes_left)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_DzExpeditionEndsWarning, sizeof(ExpeditionExpireWarning));
|
||||
auto outapp = new EQApplicationPacket(OP_DzExpeditionEndsWarning, sizeof(ExpeditionExpireWarning));
|
||||
ExpeditionExpireWarning *ew = (ExpeditionExpireWarning*)outapp->pBuffer;
|
||||
ew->minutes_remaining = minutes_left;
|
||||
|
||||
@@ -4523,6 +4647,7 @@ void EntityList::ExpeditionWarning(uint32 minutes_left)
|
||||
it->second->QueuePacket(outapp);
|
||||
++it;
|
||||
}
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
Mob *EntityList::GetClosestMobByBodyType(Mob *sender, bodyType BodyType)
|
||||
@@ -4638,7 +4763,7 @@ Mob *EntityList::GetTargetForVirus(Mob *spreader, int range)
|
||||
++it;
|
||||
}
|
||||
|
||||
if(TargetsInRange.size() == 0)
|
||||
if(TargetsInRange.empty())
|
||||
return nullptr;
|
||||
|
||||
return TargetsInRange[zone->random.Int(0, TargetsInRange.size() - 1)];
|
||||
@@ -4651,3 +4776,11 @@ void EntityList::StopMobAI()
|
||||
mob.second->AI_ShutDown();
|
||||
}
|
||||
}
|
||||
|
||||
void EntityList::SendAlternateAdvancementStats() {
|
||||
for(auto &c : client_list) {
|
||||
c.second->SendAlternateAdvancementTable();
|
||||
c.second->SendAlternateAdvancementStats();
|
||||
c.second->SendAlternateAdvancementPoints();
|
||||
}
|
||||
}
|
||||
|
||||
+50
-13
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "position.h"
|
||||
#include "zonedump.h"
|
||||
|
||||
class Encounter;
|
||||
class Beacon;
|
||||
class Client;
|
||||
class Corpse;
|
||||
@@ -40,7 +41,7 @@ class EntityList;
|
||||
class Group;
|
||||
class Merc;
|
||||
class Mob;
|
||||
class NPC;
|
||||
class NPC;
|
||||
class Object;
|
||||
class Petition;
|
||||
class Raid;
|
||||
@@ -77,6 +78,7 @@ public:
|
||||
virtual bool IsDoor() const { return false; }
|
||||
virtual bool IsTrap() const { return false; }
|
||||
virtual bool IsBeacon() const { return false; }
|
||||
virtual bool IsEncounter() const { return false; }
|
||||
|
||||
virtual bool Process() { return false; }
|
||||
virtual bool Save() { return true; }
|
||||
@@ -91,6 +93,7 @@ public:
|
||||
Doors *CastToDoors();
|
||||
Trap *CastToTrap();
|
||||
Beacon *CastToBeacon();
|
||||
Encounter *CastToEncounter();
|
||||
|
||||
const Client *CastToClient() const;
|
||||
const NPC *CastToNPC() const;
|
||||
@@ -101,6 +104,7 @@ public:
|
||||
const Doors *CastToDoors() const;
|
||||
const Trap *CastToTrap() const;
|
||||
const Beacon *CastToBeacon() const;
|
||||
const Encounter *CastToEncounter() const;
|
||||
|
||||
inline const uint16& GetID() const { return id; }
|
||||
inline const time_t& GetSpawnTimeStamp() const { return spawn_timestamp; }
|
||||
@@ -144,14 +148,29 @@ public:
|
||||
bool IsMobSpawnedByNpcTypeID(uint32 get_id);
|
||||
Mob *GetTargetForVirus(Mob* spreader, int range);
|
||||
inline NPC *GetNPCByID(uint16 id)
|
||||
{ return npc_list.count(id) ? npc_list.at(id) : nullptr; }
|
||||
{
|
||||
auto it = npc_list.find(id);
|
||||
if (it != npc_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
NPC *GetNPCByNPCTypeID(uint32 npc_id);
|
||||
inline Merc *GetMercByID(uint16 id)
|
||||
{ return merc_list.count(id) ? merc_list.at(id) : nullptr; }
|
||||
{
|
||||
auto it = merc_list.find(id);
|
||||
if (it != merc_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
Client *GetClientByName(const char *name);
|
||||
Client *GetClientByAccID(uint32 accid);
|
||||
inline Client *GetClientByID(uint16 id)
|
||||
{ return client_list.count(id) ? client_list.at(id) : nullptr; }
|
||||
{
|
||||
auto it = client_list.find(id);
|
||||
if (it != client_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
Client *GetClientByCharID(uint32 iCharID);
|
||||
Client *GetClientByWID(uint32 iWID);
|
||||
Client *GetClient(uint32 ip, uint16 port);
|
||||
@@ -168,7 +187,12 @@ public:
|
||||
Corpse *GetCorpseByOwner(Client* client);
|
||||
Corpse *GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
|
||||
inline Corpse *GetCorpseByID(uint16 id)
|
||||
{ return corpse_list.count(id) ? corpse_list.at(id) : nullptr; }
|
||||
{
|
||||
auto it = corpse_list.find(id);
|
||||
if (it != corpse_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
Corpse *GetCorpseByDBID(uint32 dbid);
|
||||
Corpse *GetCorpseByName(const char* name);
|
||||
|
||||
@@ -177,10 +201,20 @@ public:
|
||||
Client* FindCorpseDragger(uint16 CorpseID);
|
||||
|
||||
inline Object *GetObjectByID(uint16 id)
|
||||
{ return object_list.count(id) ? object_list.at(id) : nullptr; }
|
||||
{
|
||||
auto it = object_list.find(id);
|
||||
if (it != object_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
Object *GetObjectByDBID(uint32 id);
|
||||
inline Doors *GetDoorsByID(uint16 id)
|
||||
{ return door_list.count(id) ? door_list.at(id) : nullptr; }
|
||||
{
|
||||
auto it = door_list.find(id);
|
||||
if (it != door_list.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
Doors *GetDoorsByDoorID(uint32 id);
|
||||
Doors *GetDoorsByDBID(uint32 id);
|
||||
void RemoveAllCorpsesByCharID(uint32 charid);
|
||||
@@ -203,6 +237,7 @@ public:
|
||||
void MobProcess();
|
||||
void TrapProcess();
|
||||
void BeaconProcess();
|
||||
void EncounterProcess();
|
||||
void ProcessMove(Client *c, const glm::vec3& location);
|
||||
void ProcessMove(NPC *n, float x, float y, float z);
|
||||
void AddArea(int id, int type, float min_x, float max_x, float min_y, float max_y, float min_z, float max_z);
|
||||
@@ -228,6 +263,7 @@ public:
|
||||
void AddDoor(Doors* door);
|
||||
void AddTrap(Trap* trap);
|
||||
void AddBeacon(Beacon *beacon);
|
||||
void AddEncounter(Encounter *encounter);
|
||||
void AddProximity(NPC *proximity_for);
|
||||
void Clear();
|
||||
bool RemoveMob(uint16 delete_id);
|
||||
@@ -266,6 +302,7 @@ public:
|
||||
Entity *GetEntityCorpse(uint16 id);
|
||||
Entity *GetEntityTrap(uint16 id);
|
||||
Entity *GetEntityBeacon(uint16 id);
|
||||
Entity *GetEntityEncounter(uint16 id);
|
||||
Entity *GetEntityMob(const char *name);
|
||||
Entity *GetEntityCorpse(const char *name);
|
||||
|
||||
@@ -315,8 +352,8 @@ public:
|
||||
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);
|
||||
void QueueManaged(Mob* sender, const EQApplicationPacket* app, bool ignore_sender=false, bool ackreq = true);
|
||||
|
||||
void AEAttack(Mob *attacker, float dist, int Hand = MainPrimary, int count = 0, bool IsFromSpell = false);
|
||||
void AETaunt(Client *caster, float range = 0);
|
||||
void AEAttack(Mob *attacker, float dist, int Hand = EQEmu::legacy::SlotPrimary, int count = 0, bool IsFromSpell = false);
|
||||
void AETaunt(Client *caster, float range=0, int32 bonus_hate=0);
|
||||
void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0);
|
||||
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||
void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
|
||||
@@ -326,7 +363,7 @@ public:
|
||||
void SendAlarm(Trap* trap, Mob* currenttarget, uint8 kos);
|
||||
Trap* FindNearbyTrap(Mob* searcher, float max_dist);
|
||||
|
||||
void AddHealAggro(Mob* target, Mob* caster, uint16 thedam);
|
||||
void AddHealAggro(Mob* target, Mob* caster, uint16 hate);
|
||||
Mob* FindDefenseNPC(uint32 npcid);
|
||||
void OpenDoorsNear(NPC* opener);
|
||||
void UpdateWho(bool iSendFullUpdate = false);
|
||||
@@ -391,7 +428,6 @@ public:
|
||||
|
||||
void SaveAllClientsTaskState();
|
||||
void ReloadAllClientsTaskState(int TaskID=0);
|
||||
|
||||
uint16 CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time = 300000);
|
||||
uint16 CreateGroundObjectFromModel(const char *model, const glm::vec4& position, uint8 type = 0x00, uint32 decay_time = 0);
|
||||
uint16 CreateDoor(const char *model, const glm::vec4& position, uint8 type = 0, uint16 size = 100);
|
||||
@@ -422,6 +458,7 @@ public:
|
||||
uint16 GetFreeID();
|
||||
void RefreshAutoXTargets(Client *c);
|
||||
void RefreshClientXTargets(Client *c);
|
||||
void SendAlternateAdvancementStats();
|
||||
|
||||
protected:
|
||||
friend class Zone;
|
||||
@@ -448,6 +485,7 @@ private:
|
||||
std::unordered_map<uint16, Doors *> door_list;
|
||||
std::unordered_map<uint16, Trap *> trap_list;
|
||||
std::unordered_map<uint16, Beacon *> beacon_list;
|
||||
std::unordered_map<uint16, Encounter *> encounter_list;
|
||||
std::list<NPC *> proximity_list;
|
||||
std::list<Group *> group_list;
|
||||
std::list<Raid *> raid_list;
|
||||
@@ -458,7 +496,6 @@ private:
|
||||
#ifdef BOTS
|
||||
public:
|
||||
void AddBot(Bot* newBot, bool SendSpawnPacket = true, bool dontqueue = false);
|
||||
void BotPickLock(Bot* rogue);
|
||||
bool RemoveBot(uint16 entityID);
|
||||
Mob* GetMobByBotID(uint32 botID);
|
||||
Bot* GetBotByBotID(uint32 botID);
|
||||
|
||||
+3
-1
@@ -82,7 +82,9 @@ typedef enum {
|
||||
EVENT_RESPAWN,
|
||||
EVENT_DEATH_COMPLETE,
|
||||
EVENT_UNHANDLED_OPCODE,
|
||||
|
||||
EVENT_TICK,
|
||||
EVENT_SPAWN_ZONE,
|
||||
EVENT_DEATH_ZONE,
|
||||
_LargestEventID
|
||||
} QuestEventID;
|
||||
|
||||
|
||||
+164
-18
@@ -59,6 +59,97 @@ static uint32 MaxBankedRaidLeadershipPoints(int Level)
|
||||
return 10;
|
||||
}
|
||||
|
||||
uint32 Client::CalcEXP(uint8 conlevel) {
|
||||
|
||||
uint32 in_add_exp = EXP_FORMULA;
|
||||
|
||||
|
||||
if((XPRate != 0))
|
||||
in_add_exp = static_cast<uint32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
|
||||
|
||||
float totalmod = 1.0;
|
||||
float zemmod = 1.0;
|
||||
//get modifiers
|
||||
if(RuleR(Character, ExpMultiplier) >= 0){
|
||||
totalmod *= RuleR(Character, ExpMultiplier);
|
||||
}
|
||||
|
||||
if(zone->newzone_data.zone_exp_multiplier >= 0){
|
||||
zemmod *= zone->newzone_data.zone_exp_multiplier;
|
||||
}
|
||||
|
||||
if(RuleB(Character,UseRaceClassExpBonuses))
|
||||
{
|
||||
if(GetBaseRace() == HALFLING){
|
||||
totalmod *= 1.05;
|
||||
}
|
||||
|
||||
if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
||||
totalmod *= 1.05;
|
||||
}
|
||||
}
|
||||
|
||||
if(zone->IsHotzone())
|
||||
{
|
||||
totalmod += RuleR(Zone, HotZoneBonus);
|
||||
}
|
||||
|
||||
in_add_exp = uint32(float(in_add_exp) * totalmod * zemmod);
|
||||
|
||||
if(RuleB(Character,UseXPConScaling))
|
||||
{
|
||||
if (conlevel != 0xFF) {
|
||||
switch (conlevel)
|
||||
{
|
||||
case CON_GREEN:
|
||||
in_add_exp = 0;
|
||||
return 0;
|
||||
case CON_LIGHTBLUE:
|
||||
in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier)/100;
|
||||
break;
|
||||
case CON_BLUE:
|
||||
in_add_exp = in_add_exp * RuleI(Character, BlueModifier)/100;
|
||||
break;
|
||||
case CON_WHITE:
|
||||
in_add_exp = in_add_exp * RuleI(Character, WhiteModifier)/100;
|
||||
break;
|
||||
case CON_YELLOW:
|
||||
in_add_exp = in_add_exp * RuleI(Character, YellowModifier)/100;
|
||||
break;
|
||||
case CON_RED:
|
||||
in_add_exp = in_add_exp * RuleI(Character, RedModifier)/100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float aatotalmod = 1.0;
|
||||
if(zone->newzone_data.zone_exp_multiplier >= 0){
|
||||
aatotalmod *= zone->newzone_data.zone_exp_multiplier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(RuleB(Character,UseRaceClassExpBonuses))
|
||||
{
|
||||
if(GetBaseRace() == HALFLING){
|
||||
aatotalmod *= 1.05;
|
||||
}
|
||||
|
||||
if(GetClass() == ROGUE || GetClass() == WARRIOR){
|
||||
aatotalmod *= 1.05;
|
||||
}
|
||||
}
|
||||
|
||||
if(RuleB(Zone, LevelBasedEXPMods)){
|
||||
if(zone->level_exp_mod[GetLevel()].ExpMod){
|
||||
in_add_exp *= zone->level_exp_mod[GetLevel()].ExpMod;
|
||||
}
|
||||
}
|
||||
|
||||
return in_add_exp;
|
||||
}
|
||||
|
||||
void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
this->EVENT_ITEM_ScriptStopReturn();
|
||||
@@ -78,7 +169,7 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
|
||||
//figure out how much of this goes to AAs
|
||||
add_aaxp = add_exp * m_epp.perAA / 100;
|
||||
//take that ammount away from regular exp
|
||||
//take that amount away from regular exp
|
||||
add_exp -= add_aaxp;
|
||||
|
||||
float totalmod = 1.0;
|
||||
@@ -247,12 +338,22 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
Message(13, "Error in Client::SetEXP. EXP not set.");
|
||||
return; // Must be invalid class/race
|
||||
}
|
||||
uint32 i = 0;
|
||||
uint32 membercount = 0;
|
||||
if(GetGroup())
|
||||
{
|
||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (GetGroup()->members[i] != nullptr) {
|
||||
membercount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
||||
if (isrezzexp)
|
||||
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
||||
else{
|
||||
if(this->IsGrouped())
|
||||
if(membercount > 1)
|
||||
this->Message_StringID(MT_Experience, GAIN_GROUPXP);
|
||||
else if(IsRaidGrouped())
|
||||
Message_StringID(MT_Experience, GAIN_RAIDEXP);
|
||||
@@ -268,12 +369,17 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
//this ammount of exp (once these loops complete)
|
||||
uint16 check_level = GetLevel()+1;
|
||||
//see if we gained any levels
|
||||
bool level_increase = true;
|
||||
int8 level_count = 0;
|
||||
|
||||
while (set_exp >= GetEXPForLevel(check_level)) {
|
||||
check_level++;
|
||||
if (check_level > 127) { //hard level cap
|
||||
check_level = 127;
|
||||
break;
|
||||
}
|
||||
level_count++;
|
||||
|
||||
if(GetMercID())
|
||||
UpdateMercLevel();
|
||||
}
|
||||
@@ -284,6 +390,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
check_level = 2;
|
||||
break;
|
||||
}
|
||||
level_increase = false;
|
||||
if(GetMercID())
|
||||
UpdateMercLevel();
|
||||
}
|
||||
@@ -364,17 +471,21 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
|
||||
if ((GetLevel() != check_level) && !(check_level >= maxlevel)) {
|
||||
char val1[20]={0};
|
||||
if (GetLevel() == check_level-1){
|
||||
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
|
||||
SendLevelAppearance();
|
||||
/* Message(15, "You have gained a level! Welcome to level %i!", check_level); */
|
||||
}
|
||||
if (GetLevel() == check_level){
|
||||
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
|
||||
/* Message(15, "You lost a level! You are now level %i!", check_level); */
|
||||
if (level_increase)
|
||||
{
|
||||
if (level_count == 1)
|
||||
Message_StringID(MT_Experience, GAIN_LEVEL, ConvertArray(check_level, val1));
|
||||
else
|
||||
Message(15, "Welcome to level %i!", check_level);
|
||||
|
||||
if (check_level == RuleI(Character, DeathItemLossLevel))
|
||||
Message_StringID(15, CORPSE_ITEM_LOST);
|
||||
|
||||
if (check_level == RuleI(Character, DeathExpLossLevel))
|
||||
Message_StringID(15, CORPSE_EXP_LOST);
|
||||
}
|
||||
else
|
||||
Message(15, "Welcome to level %i!", check_level);
|
||||
Message_StringID(MT_Experience, LOSE_LEVEL, ConvertArray(check_level, val1));
|
||||
|
||||
#ifdef BOTS
|
||||
uint8 myoldlevel = GetLevel();
|
||||
@@ -404,14 +515,14 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
||||
if (GetLevel() < 51) {
|
||||
m_epp.perAA = 0; // turn off aa exp if they drop below 51
|
||||
} else
|
||||
SendAAStats(); //otherwise, send them an AA update
|
||||
SendAlternateAdvancementStats(); //otherwise, send them an AA update
|
||||
|
||||
//send the expdata in any case so the xp bar isnt stuck after leveling
|
||||
uint32 tmpxp1 = GetEXPForLevel(GetLevel()+1);
|
||||
uint32 tmpxp2 = GetEXPForLevel(GetLevel());
|
||||
// Quag: crash bug fix... Divide by zero when tmpxp1 and 2 equalled each other, most likely the error case from GetEXPForLevel() (invalid class, etc)
|
||||
if (tmpxp1 != tmpxp2 && tmpxp1 != 0xFFFFFFFF && tmpxp2 != 0xFFFFFFFF) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_ExpUpdate, sizeof(ExpUpdate_Struct));
|
||||
ExpUpdate_Struct* eu = (ExpUpdate_Struct*)outapp->pBuffer;
|
||||
float tmpxp = (float) ( (float) set_exp-tmpxp2 ) / ( (float) tmpxp1-tmpxp2 );
|
||||
eu->exp = (uint32)(330.0f * tmpxp);
|
||||
@@ -434,7 +545,7 @@ void Client::SetLevel(uint8 set_level, bool command)
|
||||
return;
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct));
|
||||
LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer;
|
||||
lu->level = set_level;
|
||||
if(m_pp.level2 != 0)
|
||||
@@ -554,6 +665,41 @@ uint32 Client::GetEXPForLevel(uint16 check_level)
|
||||
mod *= 1000;
|
||||
|
||||
uint32 finalxp = uint32(base * mod);
|
||||
|
||||
if(RuleB(Character,UseOldRaceExpPenalties))
|
||||
{
|
||||
float racemod = 1.0;
|
||||
if(GetBaseRace() == TROLL || GetBaseRace() == IKSAR) {
|
||||
racemod = 1.2;
|
||||
} else if(GetBaseRace() == OGRE) {
|
||||
racemod = 1.15;
|
||||
} else if(GetBaseRace() == BARBARIAN) {
|
||||
racemod = 1.05;
|
||||
} else if(GetBaseRace() == HALFLING) {
|
||||
racemod = 0.95;
|
||||
}
|
||||
|
||||
finalxp = uint32(finalxp * racemod);
|
||||
}
|
||||
|
||||
if(RuleB(Character,UseOldClassExpPenalties))
|
||||
{
|
||||
float classmod = 1.0;
|
||||
if(GetClass() == PALADIN || GetClass() == SHADOWKNIGHT || GetClass() == RANGER || GetClass() == BARD) {
|
||||
classmod = 1.4;
|
||||
} else if(GetClass() == MONK) {
|
||||
classmod = 1.2;
|
||||
} else if(GetClass() == WIZARD || GetClass() == ENCHANTER || GetClass() == MAGICIAN || GetClass() == NECROMANCER) {
|
||||
classmod = 1.1;
|
||||
} else if(GetClass() == ROGUE) {
|
||||
classmod = 0.91;
|
||||
} else if(GetClass() == WARRIOR) {
|
||||
classmod = 0.9;
|
||||
}
|
||||
|
||||
finalxp = uint32(finalxp * classmod);
|
||||
}
|
||||
|
||||
finalxp = mod_client_xp_for_level(finalxp, check_level);
|
||||
|
||||
return finalxp;
|
||||
@@ -594,8 +740,8 @@ void Group::SplitExp(uint32 exp, Mob* other) {
|
||||
groupmod = 2.16;
|
||||
else
|
||||
groupmod = 1.0;
|
||||
|
||||
groupexp += (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier)));
|
||||
if(membercount > 1 && membercount <= 6)
|
||||
groupexp += (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier)));
|
||||
|
||||
int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
|
||||
if(conlevel == CON_GREEN)
|
||||
@@ -692,7 +838,7 @@ void Client::AddLeadershipEXP(uint32 group_exp, uint32 raid_exp) {
|
||||
}
|
||||
|
||||
void Client::SendLeadershipEXPUpdate() {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_LeadershipExpUpdate, sizeof(LeadershipExpUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_LeadershipExpUpdate, sizeof(LeadershipExpUpdate_Struct));
|
||||
LeadershipExpUpdate_Struct* eu = (LeadershipExpUpdate_Struct *) outapp->pBuffer;
|
||||
|
||||
eu->group_leadership_exp = m_pp.group_leadership_exp;
|
||||
@@ -714,7 +860,7 @@ uint32 Client::GetCharMaxLevelFromQGlobal() {
|
||||
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, this->CharacterID(), zone->GetZoneID());
|
||||
}
|
||||
|
||||
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||
auto iter = globalMap.begin();
|
||||
uint32 gcount = 0;
|
||||
while(iter != globalMap.end()) {
|
||||
if((*iter).name.compare("CharMaxLevel") == 0){
|
||||
|
||||
+8
-31
@@ -33,7 +33,7 @@ extern Zone* zone;
|
||||
//this is called whenever we are damaged to process possible fleeing
|
||||
void Mob::CheckFlee() {
|
||||
//if were allready fleeing, dont need to check more...
|
||||
if(flee_mode && curfp)
|
||||
if(flee_mode && currently_fleeing)
|
||||
return;
|
||||
|
||||
//dont bother if we are immune to fleeing
|
||||
@@ -101,7 +101,7 @@ void Mob::ProcessFlee()
|
||||
//When ImmuneToFlee effect fades it will turn fear back on and check if it can still flee.
|
||||
if (flee_mode && (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) &&
|
||||
!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -118,34 +118,11 @@ void Mob::ProcessFlee()
|
||||
//see if we are legitimately feared or blind now
|
||||
if (!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
|
||||
//not feared or blind... were done...
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float Mob::GetFearSpeed()
|
||||
{
|
||||
if (flee_mode) {
|
||||
//we know ratio < FLEE_HP_RATIO
|
||||
float speed = GetBaseRunspeed();
|
||||
float ratio = GetHPRatio();
|
||||
float multiplier = RuleR(Combat, FleeMultiplier);
|
||||
|
||||
if (GetSnaredAmount() > 40)
|
||||
multiplier = multiplier / 6.0f;
|
||||
|
||||
speed = speed * ratio * multiplier / 100;
|
||||
|
||||
//NPC will eventually stop. Snares speeds this up.
|
||||
if (speed < 0.09)
|
||||
speed = 0.0001f;
|
||||
|
||||
return speed;
|
||||
}
|
||||
// fear and blind use their normal run speed
|
||||
return GetRunspeed();
|
||||
}
|
||||
|
||||
void Mob::CalculateNewFearpoint()
|
||||
{
|
||||
if(RuleB(Pathing, Fear) && zone->pathing)
|
||||
@@ -160,10 +137,10 @@ void Mob::CalculateNewFearpoint()
|
||||
|
||||
std::deque<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
|
||||
|
||||
if(Route.size() > 0)
|
||||
if(!Route.empty())
|
||||
{
|
||||
m_FearWalkTarget = glm::vec3(Loc.x, Loc.y, Loc.z);
|
||||
curfp = true;
|
||||
currently_fleeing = true;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::None, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
|
||||
return;
|
||||
@@ -174,7 +151,7 @@ void Mob::CalculateNewFearpoint()
|
||||
|
||||
int loop = 0;
|
||||
float ranx, rany, ranz;
|
||||
curfp = false;
|
||||
currently_fleeing = false;
|
||||
while (loop < 100) //Max 100 tries
|
||||
{
|
||||
int ran = 250 - (loop*2);
|
||||
@@ -187,11 +164,11 @@ void Mob::CalculateNewFearpoint()
|
||||
float fdist = ranz - GetZ();
|
||||
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
|
||||
{
|
||||
curfp = true;
|
||||
currently_fleeing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curfp)
|
||||
if (currently_fleeing)
|
||||
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
|
||||
else //Break fear
|
||||
BuffFadeByEffect(SE_Fear);
|
||||
|
||||
+61
-54
@@ -153,21 +153,21 @@ uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id,
|
||||
//we need this function to immediately determine, after we receive OP_Fishing, if we can even try to fish, otherwise we have to wait a while to get the failure
|
||||
bool Client::CanFish() {
|
||||
//make sure we still have a fishing pole on:
|
||||
const ItemInst* Pole = m_inv[MainPrimary];
|
||||
int32 bslot = m_inv.HasItemByUse(ItemTypeFishingBait, 1, invWhereWorn|invWherePersonal);
|
||||
const ItemInst* Pole = m_inv[EQEmu::legacy::SlotPrimary];
|
||||
int32 bslot = m_inv.HasItemByUse(EQEmu::item::ItemTypeFishingBait, 1, invWhereWorn | invWherePersonal);
|
||||
const ItemInst* Bait = nullptr;
|
||||
if (bslot != INVALID_INDEX)
|
||||
Bait = m_inv.GetItem(bslot);
|
||||
|
||||
if(!Pole || !Pole->IsType(ItemClassCommon) || Pole->GetItem()->ItemType != ItemTypeFishingPole) {
|
||||
if (m_inv.HasItemByUse(ItemTypeFishingPole, 1, invWhereWorn|invWherePersonal|invWhereBank|invWhereSharedBank|invWhereTrading|invWhereCursor)) //We have a fishing pole somewhere, just not equipped
|
||||
if (!Pole || !Pole->IsClassCommon() || Pole->GetItem()->ItemType != EQEmu::item::ItemTypeFishingPole) {
|
||||
if (m_inv.HasItemByUse(EQEmu::item::ItemTypeFishingPole, 1, invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor)) //We have a fishing pole somewhere, just not equipped
|
||||
Message_StringID(MT_Skills, FISHING_EQUIP_POLE); //You need to put your fishing pole in your primary hand.
|
||||
else //We don't have a fishing pole anywhere
|
||||
Message_StringID(MT_Skills, FISHING_NO_POLE); //You can't fish without a fishing pole, go buy one.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Bait || !Bait->IsType(ItemClassCommon) || Bait->GetItem()->ItemType != ItemTypeFishingBait) {
|
||||
if (!Bait || !Bait->IsClassCommon() || Bait->GetItem()->ItemType != EQEmu::item::ItemTypeFishingBait) {
|
||||
Message_StringID(MT_Skills, FISHING_NO_BAIT); //You can't fish without fishing bait, go buy some.
|
||||
return false;
|
||||
}
|
||||
@@ -185,26 +185,35 @@ bool Client::CanFish() {
|
||||
|
||||
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
||||
rodPosition.y = m_Position.y + RodLength * cos(HeadingDegrees * M_PI/180.0f);
|
||||
rodPosition.z = m_Position.z;
|
||||
|
||||
// Do BestZ to find where the line hanging from the rod intersects the water (if it is water).
|
||||
// and go 1 unit into the water.
|
||||
glm::vec3 dest;
|
||||
dest.x = rodPosition.x;
|
||||
dest.y = rodPosition.y;
|
||||
dest.z = m_Position.z+10;
|
||||
|
||||
rodPosition.z = zone->zonemap->FindBestZ(dest, nullptr) + 4;
|
||||
bool in_lava = zone->watermap->InLava(rodPosition);
|
||||
bool in_water = zone->watermap->InWater(rodPosition) || zone->watermap->InVWater(rodPosition);
|
||||
//Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava);
|
||||
if (in_lava) {
|
||||
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
|
||||
float bestz = zone->zonemap->FindBestZ(rodPosition, nullptr);
|
||||
float len = m_Position.z - bestz;
|
||||
if(len > LineLength || len < 0.0f) {
|
||||
Message_StringID(MT_Skills, FISHING_LAND);
|
||||
return false;
|
||||
}
|
||||
if((!in_water) || (m_Position.z-rodPosition.z)>LineLength) { //Didn't hit the water OR the water is too far below us
|
||||
Message_StringID(MT_Skills, FISHING_LAND); //Trying to catch land sharks perhaps?
|
||||
return false;
|
||||
|
||||
float step_size = RuleR(Watermap, FishingLineStepSize);
|
||||
|
||||
for(float i = 0.0f; i < len; i += step_size) {
|
||||
glm::vec3 dest(rodPosition.x, rodPosition.y, m_Position.z - i);
|
||||
|
||||
bool in_lava = zone->watermap->InLava(dest);
|
||||
bool in_water = zone->watermap->InWater(dest) || zone->watermap->InVWater(dest);
|
||||
|
||||
if (in_lava) {
|
||||
Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something?
|
||||
return false;
|
||||
}
|
||||
|
||||
if(in_water) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Message_StringID(MT_Skills, FISHING_LAND);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -240,16 +249,16 @@ void Client::GoFish()
|
||||
|
||||
//success formula is not researched at all
|
||||
|
||||
int fishing_skill = GetSkill(SkillFishing); //will take into account skill bonuses on pole & bait
|
||||
int fishing_skill = GetSkill(EQEmu::skills::SkillFishing); //will take into account skill bonuses on pole & bait
|
||||
|
||||
//make sure we still have a fishing pole on:
|
||||
int32 bslot = m_inv.HasItemByUse(ItemTypeFishingBait, 1, invWhereWorn|invWherePersonal);
|
||||
int32 bslot = m_inv.HasItemByUse(EQEmu::item::ItemTypeFishingBait, 1, invWhereWorn | invWherePersonal);
|
||||
const ItemInst* Bait = nullptr;
|
||||
if (bslot != INVALID_INDEX)
|
||||
Bait = m_inv.GetItem(bslot);
|
||||
|
||||
//if the bait isnt equipped, need to add its skill bonus
|
||||
if(bslot >= EmuConstants::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == SkillFishing) {
|
||||
if (bslot >= EQEmu::legacy::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == EQEmu::skills::SkillFishing) {
|
||||
fishing_skill += Bait->GetItem()->SkillModValue;
|
||||
}
|
||||
|
||||
@@ -274,14 +283,14 @@ void Client::GoFish()
|
||||
if(tmp != nullptr) {
|
||||
auto positionNPC = GetPosition();
|
||||
positionNPC.x = positionNPC.x + 3;
|
||||
NPC* npc = new NPC(tmp, nullptr, positionNPC, FlyMode3);
|
||||
npc->AddLootTable();
|
||||
auto npc = new NPC(tmp, nullptr, positionNPC, FlyMode3);
|
||||
npc->AddLootTable();
|
||||
|
||||
npc->AddToHateList(this, 1, 0, false); //no help yelling
|
||||
npc->AddToHateList(this, 1, 0, false); // no help yelling
|
||||
|
||||
entity_list.AddNPC(npc);
|
||||
entity_list.AddNPC(npc);
|
||||
|
||||
Message(MT_Emote, "You fish up a little more than you bargained for...");
|
||||
Message(MT_Emote, "You fish up a little more than you bargained for...");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +304,7 @@ void Client::GoFish()
|
||||
food_id = common_fish_ids[index];
|
||||
}
|
||||
|
||||
const Item_Struct* food_item = database.GetItem(food_id);
|
||||
const EQEmu::ItemBase* food_item = database.GetItem(food_id);
|
||||
|
||||
Message_StringID(MT_Skills, FISHING_SUCCESS);
|
||||
ItemInst* inst = database.CreateItem(food_item, 1);
|
||||
@@ -308,12 +317,12 @@ void Client::GoFish()
|
||||
else
|
||||
{
|
||||
PushItemOnCursor(*inst);
|
||||
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
|
||||
SendItemPacket(EQEmu::legacy::SlotCursor, inst, ItemPacketLimbo);
|
||||
if(RuleB(TaskSystem, EnableTaskSystem))
|
||||
UpdateTasksForItem(ActivityFish, food_id);
|
||||
|
||||
safe_delete(inst);
|
||||
inst = m_inv.GetItem(MainCursor);
|
||||
inst = m_inv.GetItem(EQEmu::legacy::SlotCursor);
|
||||
}
|
||||
|
||||
if(inst) {
|
||||
@@ -345,19 +354,19 @@ void Client::GoFish()
|
||||
//and then swap out items in primary slot... too lazy to fix right now
|
||||
if (zone->random.Int(0, 49) == 1) {
|
||||
Message_StringID(MT_Skills, FISHING_POLE_BROKE); //Your fishing pole broke!
|
||||
DeleteItemInInventory(MainPrimary, 0, true);
|
||||
DeleteItemInInventory(EQEmu::legacy::SlotPrimary, 0, true);
|
||||
}
|
||||
|
||||
if(CheckIncreaseSkill(SkillFishing, nullptr, 5))
|
||||
if (CheckIncreaseSkill(EQEmu::skills::SkillFishing, nullptr, 5))
|
||||
{
|
||||
if(title_manager.IsNewTradeSkillTitleAvailable(SkillFishing, GetRawSkill(SkillFishing)))
|
||||
if (title_manager.IsNewTradeSkillTitleAvailable(EQEmu::skills::SkillFishing, GetRawSkill(EQEmu::skills::SkillFishing)))
|
||||
NotifyNewTitlesAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::ForageItem(bool guarantee) {
|
||||
|
||||
int skill_level = GetSkill(SkillForage);
|
||||
int skill_level = GetSkill(EQEmu::skills::SkillForage);
|
||||
|
||||
//be wary of the string ids in switch below when changing this.
|
||||
uint32 common_food_ids[MAX_COMMON_FOOD_IDS] = {
|
||||
@@ -387,7 +396,7 @@ void Client::ForageItem(bool guarantee) {
|
||||
foragedfood = common_food_ids[index];
|
||||
}
|
||||
|
||||
const Item_Struct* food_item = database.GetItem(foragedfood);
|
||||
const EQEmu::ItemBase* food_item = database.GetItem(foragedfood);
|
||||
|
||||
if(!food_item) {
|
||||
Log.Out(Logs::General, Logs::Error, "nullptr returned from database.GetItem in ClientForageItem");
|
||||
@@ -398,20 +407,18 @@ void Client::ForageItem(bool guarantee) {
|
||||
stringid = FORAGE_GRUBS;
|
||||
else
|
||||
switch(food_item->ItemType) {
|
||||
|
||||
case ItemTypeFood:
|
||||
stringid = FORAGE_FOOD;
|
||||
break;
|
||||
|
||||
case ItemTypeDrink:
|
||||
if(strstr(food_item->Name, "ater"))
|
||||
stringid = FORAGE_WATER;
|
||||
else
|
||||
stringid = FORAGE_DRINK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case EQEmu::item::ItemTypeFood:
|
||||
stringid = FORAGE_FOOD;
|
||||
break;
|
||||
case EQEmu::item::ItemTypeDrink:
|
||||
if(strstr(food_item->Name, "ater"))
|
||||
stringid = FORAGE_WATER;
|
||||
else
|
||||
stringid = FORAGE_DRINK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Message_StringID(MT_Skills, stringid);
|
||||
ItemInst* inst = database.CreateItem(food_item, 1);
|
||||
@@ -424,12 +431,12 @@ void Client::ForageItem(bool guarantee) {
|
||||
}
|
||||
else {
|
||||
PushItemOnCursor(*inst);
|
||||
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
|
||||
SendItemPacket(EQEmu::legacy::SlotCursor, inst, ItemPacketLimbo);
|
||||
if(RuleB(TaskSystem, EnableTaskSystem))
|
||||
UpdateTasksForItem(ActivityForage, foragedfood);
|
||||
|
||||
safe_delete(inst);
|
||||
inst = m_inv.GetItem(MainCursor);
|
||||
inst = m_inv.GetItem(EQEmu::legacy::SlotCursor);
|
||||
}
|
||||
|
||||
if(inst) {
|
||||
@@ -450,7 +457,7 @@ void Client::ForageItem(bool guarantee) {
|
||||
parse->EventPlayer(EVENT_FORAGE_FAILURE, this, "", 0);
|
||||
}
|
||||
|
||||
CheckIncreaseSkill(SkillForage, nullptr, 5);
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillForage, nullptr, 5);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+92
-31
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
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
|
||||
@@ -15,6 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "masterentity.h"
|
||||
@@ -271,7 +272,7 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
|
||||
int x=1;
|
||||
|
||||
//build the template join packet
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
strcpy(gj->membername, NewMemberName);
|
||||
gj->action = groupActJoin;
|
||||
@@ -394,7 +395,7 @@ void Group::SendHPPacketsTo(Mob *member)
|
||||
{
|
||||
members[i]->CreateHPPacket(&hpapp);
|
||||
member->CastToClient()->QueuePacket(&hpapp, false);
|
||||
if(member->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
|
||||
if (member->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
|
||||
{
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
|
||||
@@ -425,7 +426,7 @@ void Group::SendHPPacketsFrom(Mob *member)
|
||||
if(members[i] && members[i] != member && members[i]->IsClient())
|
||||
{
|
||||
members[i]->CastToClient()->QueuePacket(&hp_app);
|
||||
if(members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
|
||||
if (members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
|
||||
{
|
||||
outapp.SetOpcode(OP_MobManaUpdate);
|
||||
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
|
||||
@@ -533,7 +534,7 @@ void Group::SendGroupJoinOOZ(Mob* NewMember) {
|
||||
}
|
||||
|
||||
//send updates to clients out of zone...
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GroupJoin, sizeof(ServerGroupJoin_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_GroupJoin, sizeof(ServerGroupJoin_Struct));
|
||||
ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack->pBuffer;
|
||||
gj->gid = GetID();
|
||||
gj->zoneid = zone->GetZoneID();
|
||||
@@ -565,7 +566,7 @@ bool Group::DelMemberOOZ(const char *Name) {
|
||||
if(GroupCount() < 3)
|
||||
{
|
||||
UnDelegateMarkNPC(NPCMarkerName.c_str());
|
||||
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < ClientVersion::SoD) {
|
||||
if (GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->ClientVersion() < EQEmu::versions::ClientVersion::SoD) {
|
||||
UnDelegateMainAssist(MainAssistName.c_str());
|
||||
}
|
||||
ClearAllNPCMarks();
|
||||
@@ -633,7 +634,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
return true;
|
||||
}
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GroupLeave, sizeof(ServerGroupLeave_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_GroupLeave, sizeof(ServerGroupLeave_Struct));
|
||||
ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer;
|
||||
gl->gid = GetID();
|
||||
gl->zoneid = zone->GetZoneID();
|
||||
@@ -642,7 +643,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gu = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
gu->action = groupActLeave;
|
||||
strcpy(gu->membername, oldmember->GetCleanName());
|
||||
@@ -723,7 +724,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
if(GroupCount() < 3)
|
||||
{
|
||||
UnDelegateMarkNPC(NPCMarkerName.c_str());
|
||||
if(GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->GetClientVersion() < ClientVersion::SoD) {
|
||||
if (GetLeader() && GetLeader()->IsClient() && GetLeader()->CastToClient()->ClientVersion() < EQEmu::versions::ClientVersion::SoD) {
|
||||
UnDelegateMainAssist(MainAssistName.c_str());
|
||||
}
|
||||
ClearAllNPCMarks();
|
||||
@@ -846,7 +847,8 @@ void Group::GroupMessage(Mob* sender, uint8 language, uint8 lang_skill, const ch
|
||||
members[i]->CastToClient()->ChannelMessageSend(sender->GetName(),members[i]->GetName(),2,language,lang_skill,message);
|
||||
}
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_OOZGroupMessage, sizeof(ServerGroupChannelMessage_Struct) + strlen(message) + 1);
|
||||
auto pack =
|
||||
new ServerPacket(ServerOP_OOZGroupMessage, sizeof(ServerGroupChannelMessage_Struct) + strlen(message) + 1);
|
||||
ServerGroupChannelMessage_Struct* gcm = (ServerGroupChannelMessage_Struct*)pack->pBuffer;
|
||||
gcm->zoneid = zone->GetZoneID();
|
||||
gcm->groupid = GetID();
|
||||
@@ -871,7 +873,7 @@ uint32 Group::GetTotalGroupDamage(Mob* other) {
|
||||
}
|
||||
|
||||
void Group::DisbandGroup() {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate_Struct));
|
||||
|
||||
GroupUpdate_Struct* gu = (GroupUpdate_Struct*) outapp->pBuffer;
|
||||
gu->action = groupActDisband;
|
||||
@@ -915,7 +917,7 @@ void Group::DisbandGroup() {
|
||||
|
||||
ClearAllNPCMarks();
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_DisbandGroup, sizeof(ServerDisbandGroup_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_DisbandGroup, sizeof(ServerDisbandGroup_Struct));
|
||||
ServerDisbandGroup_Struct* dg = (ServerDisbandGroup_Struct*)pack->pBuffer;
|
||||
dg->zoneid = zone->GetZoneID();
|
||||
dg->groupid = GetID();
|
||||
@@ -938,6 +940,41 @@ void Group::DisbandGroup() {
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Group::GetMemberList(std::list<Mob*>& member_list, bool clear_list)
|
||||
{
|
||||
if (clear_list)
|
||||
member_list.clear();
|
||||
|
||||
for (auto member_iter : members) {
|
||||
if (member_iter)
|
||||
member_list.push_back(member_iter);
|
||||
}
|
||||
}
|
||||
|
||||
void Group::GetClientList(std::list<Client*>& client_list, bool clear_list)
|
||||
{
|
||||
if (clear_list)
|
||||
client_list.clear();
|
||||
|
||||
for (auto client_iter : members) {
|
||||
if (client_iter && client_iter->IsClient())
|
||||
client_list.push_back(client_iter->CastToClient());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
void Group::GetBotList(std::list<Bot*>& bot_list, bool clear_list)
|
||||
{
|
||||
if (clear_list)
|
||||
bot_list.clear();
|
||||
|
||||
for (auto bot_iter : members) {
|
||||
if (bot_iter && bot_iter->IsBot())
|
||||
bot_list.push_back(bot_iter->CastToBot());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Group::Process() {
|
||||
if(disbandcheck && !GroupCount())
|
||||
return false;
|
||||
@@ -951,7 +988,7 @@ void Group::SendUpdate(uint32 type, Mob* member)
|
||||
if(!member->IsClient())
|
||||
return;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate2_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate2_Struct));
|
||||
GroupUpdate2_Struct* gu = (GroupUpdate2_Struct*)outapp->pBuffer;
|
||||
gu->action = type;
|
||||
strcpy(gu->yourname,member->GetName());
|
||||
@@ -985,7 +1022,7 @@ void Group::SendLeadershipAAUpdate()
|
||||
// If a group member is not in the same zone as the leader when the leader purchases a new AA, they will not become
|
||||
// aware of it until they are next in the same zone as the leader.
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
|
||||
gu->action = groupActAAUpdate;
|
||||
gu->leader_aas = LeaderAbilities;
|
||||
@@ -1392,7 +1429,7 @@ void Group::MarkNPC(Mob* Target, int Number)
|
||||
|
||||
MarkedNPCs[Number - 1] = EntityID;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||
|
||||
MarkNPC_Struct* mnpcs = (MarkNPC_Struct *)outapp->pBuffer;
|
||||
|
||||
@@ -1568,7 +1605,7 @@ void Group::NotifyMainTank(Client *c, uint8 toggle)
|
||||
if(!MainTankName.size())
|
||||
return;
|
||||
|
||||
if(c->GetClientVersion() < ClientVersion::SoD)
|
||||
if (c->ClientVersion() < EQEmu::versions::ClientVersion::SoD)
|
||||
{
|
||||
if(toggle)
|
||||
c->Message(0, "%s is now Main Tank.", MainTankName.c_str());
|
||||
@@ -1577,7 +1614,7 @@ void Group::NotifyMainTank(Client *c, uint8 toggle)
|
||||
}
|
||||
else
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GroupRoles, sizeof(GroupRole_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupRoles, sizeof(GroupRole_Struct));
|
||||
|
||||
GroupRole_Struct *grs = (GroupRole_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -1608,9 +1645,9 @@ void Group::NotifyMainAssist(Client *c, uint8 toggle)
|
||||
if(!MainAssistName.size())
|
||||
return;
|
||||
|
||||
if(c->GetClientVersion() < ClientVersion::SoD)
|
||||
if (c->ClientVersion() < EQEmu::versions::ClientVersion::SoD)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
|
||||
DelegateAbility_Struct* das = (DelegateAbility_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -1630,7 +1667,7 @@ void Group::NotifyMainAssist(Client *c, uint8 toggle)
|
||||
}
|
||||
else
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GroupRoles, sizeof(GroupRole_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupRoles, sizeof(GroupRole_Struct));
|
||||
|
||||
GroupRole_Struct *grs = (GroupRole_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -1663,7 +1700,7 @@ void Group::NotifyPuller(Client *c, uint8 toggle)
|
||||
if(!PullerName.size())
|
||||
return;
|
||||
|
||||
if(c->GetClientVersion() < ClientVersion::SoD)
|
||||
if (c->ClientVersion() < EQEmu::versions::ClientVersion::SoD)
|
||||
{
|
||||
if(toggle)
|
||||
c->Message(0, "%s is now Puller.", PullerName.c_str());
|
||||
@@ -1672,7 +1709,7 @@ void Group::NotifyPuller(Client *c, uint8 toggle)
|
||||
}
|
||||
else
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GroupRoles, sizeof(GroupRole_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupRoles, sizeof(GroupRole_Struct));
|
||||
|
||||
GroupRole_Struct *grs = (GroupRole_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -1724,7 +1761,7 @@ void Group::UnDelegateMainAssist(const char *OldMainAssistName, uint8 toggle)
|
||||
// informing them of the change and update the group_leaders table.
|
||||
//
|
||||
if(OldMainAssistName == MainAssistName) {
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
|
||||
DelegateAbility_Struct* das = (DelegateAbility_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -1882,7 +1919,7 @@ void Group::NotifyAssistTarget(Client *c)
|
||||
if(!c)
|
||||
return;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SetGroupTarget, sizeof(MarkNPC_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_SetGroupTarget, sizeof(MarkNPC_Struct));
|
||||
|
||||
MarkNPC_Struct* mnpcs = (MarkNPC_Struct *)outapp->pBuffer;
|
||||
|
||||
@@ -1955,7 +1992,7 @@ void Group::NotifyMarkNPC(Client *c)
|
||||
if(!NPCMarkerName.size())
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
|
||||
DelegateAbility_Struct* das = (DelegateAbility_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -1997,7 +2034,7 @@ void Group::UnDelegateMarkNPC(const char *OldNPCMarkerName)
|
||||
if(!NPCMarkerName.size())
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_DelegateAbility, sizeof(DelegateAbility_Struct));
|
||||
|
||||
DelegateAbility_Struct* das = (DelegateAbility_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -2031,8 +2068,8 @@ void Group::SaveGroupLeaderAA()
|
||||
{
|
||||
// Stores the Group Leaders Leadership AA data from the Player Profile as a blob in the group_leaders table.
|
||||
// This is done so that group members not in the same zone as the Leader still have access to this information.
|
||||
char *queryBuffer = new char[sizeof(GroupLeadershipAA_Struct) * 2 + 1];
|
||||
database.DoEscapeString(queryBuffer, (char*)&LeaderAbilities, sizeof(GroupLeadershipAA_Struct));
|
||||
auto queryBuffer = new char[sizeof(GroupLeadershipAA_Struct) * 2 + 1];
|
||||
database.DoEscapeString(queryBuffer, (char *)&LeaderAbilities, sizeof(GroupLeadershipAA_Struct));
|
||||
|
||||
std::string query = "UPDATE group_leaders SET leadershipaa = '";
|
||||
query += queryBuffer;
|
||||
@@ -2081,7 +2118,7 @@ void Group::SendMarkedNPCsToMember(Client *c, bool Clear)
|
||||
if(!c)
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||
|
||||
MarkNPC_Struct *mnpcs = (MarkNPC_Struct *)outapp->pBuffer;
|
||||
|
||||
@@ -2216,7 +2253,7 @@ void Group::ChangeLeader(Mob* newleader)
|
||||
|
||||
Mob* oldleader = GetLeader();
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gu = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
gu->action = groupActMakeLeader;
|
||||
|
||||
@@ -2229,7 +2266,7 @@ void Group::ChangeLeader(Mob* newleader)
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (members[i] && members[i]->IsClient())
|
||||
{
|
||||
if(members[i]->CastToClient()->GetClientVersion() >= ClientVersion::SoD)
|
||||
if (members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
|
||||
members[i]->CastToClient()->SendGroupLeaderChangePacket(newleader->GetName());
|
||||
|
||||
members[i]->CastToClient()->QueuePacket(outapp);
|
||||
@@ -2294,6 +2331,30 @@ void Group::SetPuller(const char *NewPullerName)
|
||||
}
|
||||
}
|
||||
|
||||
bool Group::AmIMainTank(const char *mob_name)
|
||||
{
|
||||
if (!mob_name)
|
||||
return false;
|
||||
|
||||
return !((bool)MainTankName.compare(mob_name));
|
||||
}
|
||||
|
||||
bool Group::AmIMainAssist(const char *mob_name)
|
||||
{
|
||||
if (!mob_name)
|
||||
return false;
|
||||
|
||||
return !((bool)MainTankName.compare(mob_name));
|
||||
}
|
||||
|
||||
bool Group::AmIPuller(const char *mob_name)
|
||||
{
|
||||
if (!mob_name)
|
||||
return false;
|
||||
|
||||
return !((bool)PullerName.compare(mob_name));
|
||||
}
|
||||
|
||||
bool Group::HasRole(Mob *m, uint8 Role)
|
||||
{
|
||||
if(!m)
|
||||
|
||||
+9
-1
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
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
|
||||
@@ -59,6 +59,11 @@ public:
|
||||
bool DelMemberOOZ(const char *Name);
|
||||
bool DelMember(Mob* oldmember,bool ignoresender = false);
|
||||
void DisbandGroup();
|
||||
void GetMemberList(std::list<Mob*>& member_list, bool clear_list = true);
|
||||
void GetClientList(std::list<Client*>& client_list, bool clear_list = true);
|
||||
#ifdef BOTS
|
||||
void GetBotList(std::list<Bot*>& bot_list, bool clear_list = true);
|
||||
#endif
|
||||
bool IsGroupMember(Mob* client);
|
||||
bool IsGroupMember(const char *Name);
|
||||
bool Process();
|
||||
@@ -123,6 +128,9 @@ public:
|
||||
const char *GetMainTankName() { return MainTankName.c_str(); }
|
||||
const char *GetMainAssistName() { return MainAssistName.c_str(); }
|
||||
const char *GetPullerName() { return PullerName.c_str(); }
|
||||
bool AmIMainTank(const char *mob_name);
|
||||
bool AmIMainAssist(const char *mob_name);
|
||||
bool AmIPuller(const char *mob_name);
|
||||
void SetNPCMarker(const char *NewNPCMarkerName);
|
||||
void UnMarkNPC(uint16 ID);
|
||||
void SendMarkedNPCsToMember(Client *c, bool Clear = false);
|
||||
|
||||
+19
-13
@@ -26,7 +26,7 @@
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void Client::SendGuildMOTD(bool GetGuildMOTDReply) {
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMOTD, sizeof(GuildMOTD_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildMOTD, sizeof(GuildMOTD_Struct));
|
||||
|
||||
// When the Client gets an OP_GuildMOTD, it compares the text to the version it has previously stored.
|
||||
// If the text in the OP_GuildMOTD packet is the same, it does nothing. If not the same, it displays
|
||||
@@ -63,12 +63,13 @@ void Client::SendGuildMOTD(bool GetGuildMOTDReply) {
|
||||
|
||||
void Client::SendGuildURL()
|
||||
{
|
||||
if(GetClientVersion() < ClientVersion::SoF)
|
||||
if (ClientVersion() < EQEmu::versions::ClientVersion::SoF)
|
||||
return;
|
||||
|
||||
if(IsInAGuild())
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateURLAndChannel_Struct));
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateURLAndChannel_Struct));
|
||||
|
||||
GuildUpdateURLAndChannel_Struct *guuacs = (GuildUpdateURLAndChannel_Struct*) outapp->pBuffer;
|
||||
|
||||
@@ -84,12 +85,13 @@ void Client::SendGuildURL()
|
||||
|
||||
void Client::SendGuildChannel()
|
||||
{
|
||||
if(GetClientVersion() < ClientVersion::SoF)
|
||||
if (ClientVersion() < EQEmu::versions::ClientVersion::SoF)
|
||||
return;
|
||||
|
||||
if(IsInAGuild())
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateURLAndChannel_Struct));
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateURLAndChannel_Struct));
|
||||
|
||||
GuildUpdateURLAndChannel_Struct *guuacs = (GuildUpdateURLAndChannel_Struct*) outapp->pBuffer;
|
||||
|
||||
@@ -106,7 +108,7 @@ void Client::SendGuildChannel()
|
||||
|
||||
void Client::SendGuildRanks()
|
||||
{
|
||||
if(GetClientVersion() < ClientVersion::RoF)
|
||||
if (ClientVersion() < EQEmu::versions::ClientVersion::RoF)
|
||||
return;
|
||||
|
||||
int permissions = 30 + 1; //Static number of permissions in all EQ clients as of May 2014
|
||||
@@ -119,7 +121,8 @@ void Client::SendGuildRanks()
|
||||
{
|
||||
while(i < permissions)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateRanks_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildUpdateURLAndChannel,
|
||||
sizeof(GuildUpdateRanks_Struct));
|
||||
GuildUpdateRanks_Struct *guuacs = (GuildUpdateRanks_Struct*) outapp->pBuffer;
|
||||
//guuacs->Unknown0008 = this->GuildID();
|
||||
strncpy(guuacs->Unknown0012, this->GetCleanName(), 64);
|
||||
@@ -149,7 +152,7 @@ void Client::SendGuildSpawnAppearance() {
|
||||
uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID());
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank);
|
||||
SendAppearancePacket(AT_GuildID, GuildID());
|
||||
if(GetClientVersion() >= ClientVersion::RoF)
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
|
||||
{
|
||||
switch (rank) {
|
||||
case 0: { rank = 5; break; } // GUILD_MEMBER 0
|
||||
@@ -187,7 +190,7 @@ void Client::SendGuildMembers() {
|
||||
if(data == nullptr)
|
||||
return; //invalid guild, shouldent happen.
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GuildMemberList);
|
||||
auto outapp = new EQApplicationPacket(OP_GuildMemberList);
|
||||
outapp->size = len;
|
||||
outapp->pBuffer = data;
|
||||
data = nullptr;
|
||||
@@ -196,7 +199,8 @@ void Client::SendGuildMembers() {
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_RequestOnlineGuildMembers, sizeof(ServerRequestOnlineGuildMembers_Struct));
|
||||
auto pack =
|
||||
new ServerPacket(ServerOP_RequestOnlineGuildMembers, sizeof(ServerRequestOnlineGuildMembers_Struct));
|
||||
|
||||
ServerRequestOnlineGuildMembers_Struct *srogms = (ServerRequestOnlineGuildMembers_Struct*)pack->pBuffer;
|
||||
|
||||
@@ -235,7 +239,7 @@ void Client::RefreshGuildInfo()
|
||||
{
|
||||
if(WasBanker != GuildBanker)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SetGuildRank, sizeof(GuildSetRank_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_SetGuildRank, sizeof(GuildSetRank_Struct));
|
||||
|
||||
GuildSetRank_Struct *gsrs = (GuildSetRank_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -248,7 +252,9 @@ void Client::RefreshGuildInfo()
|
||||
|
||||
if((guild_id != OldGuildID) && GuildBanks)
|
||||
{
|
||||
ClearGuildBank();
|
||||
// Unsure about this for RoF+ ... But they don't have that action anymore so fuck it
|
||||
if (ClientVersion() < EQEmu::versions::ClientVersion::RoF)
|
||||
ClearGuildBank();
|
||||
|
||||
if(guild_id != GUILD_NONE)
|
||||
GuildBanks->SendGuildBank(this);
|
||||
@@ -326,7 +332,7 @@ void EntityList::SendGuildList() {
|
||||
}
|
||||
|
||||
void Client::SendGuildJoin(GuildJoin_Struct* gj){
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GuildManageAdd, sizeof(GuildJoin_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildManageAdd, sizeof(GuildJoin_Struct));
|
||||
GuildJoin_Struct* outgj=(GuildJoin_Struct*)outapp->pBuffer;
|
||||
outgj->class_ = gj->class_;
|
||||
outgj->guild_id = gj->guild_id;
|
||||
|
||||
+159
-98
@@ -29,11 +29,11 @@ ZoneGuildManager guild_mgr;
|
||||
GuildBankManager *GuildBanks;
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
void ZoneGuildManager::SendGuildRefresh(uint32 guild_id, bool name, bool motd, bool rank, bool relation) {
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending guild refresh for %d to world, changes: name=%d, motd=%d, rank=d, relation=%d", guild_id, name, motd, rank, relation);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, sizeof(ServerGuildRefresh_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_RefreshGuild, sizeof(ServerGuildRefresh_Struct));
|
||||
ServerGuildRefresh_Struct *s = (ServerGuildRefresh_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
s->name_change = name;
|
||||
@@ -58,7 +58,7 @@ void ZoneGuildManager::SendCharRefresh(uint32 old_guild_id, uint32 guild_id, uin
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending char refresh for %d from guild %d to world", charid, guild_id);
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GuildCharRefresh, sizeof(ServerGuildCharRefresh_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_GuildCharRefresh, sizeof(ServerGuildCharRefresh_Struct));
|
||||
ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
s->old_guild_id = old_guild_id;
|
||||
@@ -74,7 +74,7 @@ void ZoneGuildManager::SendRankUpdate(uint32 CharID)
|
||||
if(!GetCharInfo(CharID, gci))
|
||||
return;
|
||||
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GuildRankUpdate, sizeof(ServerGuildRankUpdate_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_GuildRankUpdate, sizeof(ServerGuildRankUpdate_Struct));
|
||||
|
||||
ServerGuildRankUpdate_Struct *sgrus = (ServerGuildRankUpdate_Struct*)pack->pBuffer;
|
||||
|
||||
@@ -90,7 +90,7 @@ void ZoneGuildManager::SendRankUpdate(uint32 CharID)
|
||||
|
||||
void ZoneGuildManager::SendGuildDelete(uint32 guild_id) {
|
||||
Log.Out(Logs::Detail, Logs::Guilds, "Sending guild delete for guild %d to world", guild_id);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_DeleteGuild, sizeof(ServerGuildID_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_DeleteGuild, sizeof(ServerGuildID_Struct));
|
||||
ServerGuildID_Struct *s = (ServerGuildID_Struct *) pack->pBuffer;
|
||||
s->guild_id = guild_id;
|
||||
worldserver.SendPacket(pack);
|
||||
@@ -322,7 +322,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
else if(c != nullptr && s->guild_id != GUILD_NONE) {
|
||||
//char is in zone, and has changed into a new guild, send MOTD.
|
||||
c->SendGuildMOTD();
|
||||
if(c->GetClientVersion() >= ClientVersion::RoF)
|
||||
if (c->ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
|
||||
{
|
||||
c->SendGuildRanks();
|
||||
}
|
||||
@@ -334,7 +334,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
case ServerOP_GuildRankUpdate:
|
||||
{
|
||||
if(ZoneLoaded)
|
||||
if(is_zone_loaded)
|
||||
{
|
||||
if(pack->size != sizeof(ServerGuildRankUpdate_Struct))
|
||||
{
|
||||
@@ -346,7 +346,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
ServerGuildRankUpdate_Struct *sgrus = (ServerGuildRankUpdate_Struct*)pack->pBuffer;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SetGuildRank, sizeof(GuildSetRank_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_SetGuildRank, sizeof(GuildSetRank_Struct));
|
||||
|
||||
GuildSetRank_Struct *gsrs = (GuildSetRank_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -388,9 +388,9 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
{
|
||||
ServerGuildMemberUpdate_Struct *sgmus = (ServerGuildMemberUpdate_Struct*)pack->pBuffer;
|
||||
|
||||
if(ZoneLoaded)
|
||||
if(is_zone_loaded)
|
||||
{
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
|
||||
|
||||
GuildMemberUpdate_Struct *gmus = (GuildMemberUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
@@ -407,7 +407,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
break;
|
||||
}
|
||||
case ServerOP_OnlineGuildMembersResponse:
|
||||
if (ZoneLoaded)
|
||||
if (is_zone_loaded)
|
||||
{
|
||||
char *Buffer = (char *)pack->pBuffer;
|
||||
|
||||
@@ -421,7 +421,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
break;
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::Guilds,"Processing ServerOP_OnlineGuildMembersResponse");
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
|
||||
GuildMemberUpdate_Struct *gmus = (GuildMemberUpdate_Struct*)outapp->pBuffer;
|
||||
char Name[64];
|
||||
gmus->LastSeen = time(nullptr);
|
||||
@@ -443,7 +443,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
case ServerOP_LFGuildUpdate:
|
||||
{
|
||||
if(ZoneLoaded)
|
||||
if(is_zone_loaded)
|
||||
{
|
||||
char GuildName[33];
|
||||
char Comments[257];
|
||||
@@ -464,7 +464,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
if(GuildID == GUILD_NONE)
|
||||
break;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_GuildToggle_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_GuildToggle_Struct));
|
||||
|
||||
LFGuild_GuildToggle_Struct *gts = (LFGuild_GuildToggle_Struct *)outapp->pBuffer;
|
||||
gts->Command = 1;
|
||||
@@ -487,7 +487,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
|
||||
|
||||
void ZoneGuildManager::SendGuildMemberUpdateToWorld(const char *MemberName, uint32 GuildID, uint16 ZoneID, uint32 LastSeen)
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_GuildMemberUpdate, sizeof(ServerGuildMemberUpdate_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_GuildMemberUpdate, sizeof(ServerGuildMemberUpdate_Struct));
|
||||
|
||||
ServerGuildMemberUpdate_Struct *sgmus = (ServerGuildMemberUpdate_Struct*)pack->pBuffer;
|
||||
sgmus->GuildID = GuildID;
|
||||
@@ -501,7 +501,8 @@ void ZoneGuildManager::SendGuildMemberUpdateToWorld(const char *MemberName, uint
|
||||
|
||||
void ZoneGuildManager::RequestOnlineGuildMembers(uint32 FromID, uint32 GuildID)
|
||||
{
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_RequestOnlineGuildMembers, sizeof(ServerRequestOnlineGuildMembers_Struct));
|
||||
auto pack =
|
||||
new ServerPacket(ServerOP_RequestOnlineGuildMembers, sizeof(ServerRequestOnlineGuildMembers_Struct));
|
||||
ServerRequestOnlineGuildMembers_Struct *srogm = (ServerRequestOnlineGuildMembers_Struct*)pack->pBuffer;
|
||||
|
||||
srogm->FromID = FromID;
|
||||
@@ -526,7 +527,7 @@ void ZoneGuildManager::ProcessApproval()
|
||||
|
||||
void ZoneGuildManager::AddGuildApproval(const char* guildname,Client* owner)
|
||||
{
|
||||
GuildApproval* tmp = new GuildApproval(guildname,owner,GetFreeID());
|
||||
auto tmp = new GuildApproval(guildname, owner, GetFreeID());
|
||||
list.Insert(tmp);
|
||||
}
|
||||
|
||||
@@ -586,7 +587,7 @@ GuildApproval* ZoneGuildManager::FindGuildByOwnerApproval(Client* owner)
|
||||
|
||||
GuildBankManager::~GuildBankManager()
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = Banks.begin();
|
||||
auto Iterator = Banks.begin();
|
||||
|
||||
while(Iterator != Banks.end())
|
||||
{
|
||||
@@ -606,57 +607,56 @@ bool GuildBankManager::Load(uint32 guildID)
|
||||
return false;
|
||||
}
|
||||
|
||||
GuildBank *bank = new GuildBank;
|
||||
auto bank = new GuildBank;
|
||||
|
||||
bank->GuildID = guildID;
|
||||
bank->GuildID = guildID;
|
||||
|
||||
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
||||
bank->Items.MainArea[i].ItemID = 0;
|
||||
for (int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
||||
bank->Items.MainArea[i].ItemID = 0;
|
||||
|
||||
for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
|
||||
bank->Items.DepositArea[i].ItemID = 0;
|
||||
for (int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
|
||||
bank->Items.DepositArea[i].ItemID = 0;
|
||||
|
||||
char donator[64], whoFor[64];
|
||||
char donator[64], whoFor[64];
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
int area = atoi(row[0]);
|
||||
int slot = atoi(row[1]);
|
||||
int itemID = atoi(row[2]);
|
||||
int qty = atoi(row[3]);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
int area = atoi(row[0]);
|
||||
int slot = atoi(row[1]);
|
||||
int itemID = atoi(row[2]);
|
||||
int qty = atoi(row[3]);
|
||||
|
||||
if(row[4])
|
||||
strn0cpy(donator, row[4], sizeof(donator));
|
||||
else
|
||||
donator[0] = '\0';
|
||||
if (row[4])
|
||||
strn0cpy(donator, row[4], sizeof(donator));
|
||||
else
|
||||
donator[0] = '\0';
|
||||
|
||||
int permissions = atoi(row[5]);
|
||||
int permissions = atoi(row[5]);
|
||||
|
||||
if(row[6])
|
||||
strn0cpy(whoFor, row[6], sizeof(whoFor));
|
||||
else
|
||||
whoFor[0] = '\0';
|
||||
if (row[6])
|
||||
strn0cpy(whoFor, row[6], sizeof(whoFor));
|
||||
else
|
||||
whoFor[0] = '\0';
|
||||
|
||||
if(slot < 0)
|
||||
continue;
|
||||
if (slot < 0)
|
||||
continue;
|
||||
|
||||
GuildBankItem *itemSection = nullptr;
|
||||
GuildBankItem *itemSection = nullptr;
|
||||
|
||||
if (area == GuildBankMainArea && slot < GUILD_BANK_MAIN_AREA_SIZE)
|
||||
itemSection = bank->Items.MainArea;
|
||||
else if (area != GuildBankMainArea && slot < GUILD_BANK_DEPOSIT_AREA_SIZE)
|
||||
itemSection = bank->Items.DepositArea;
|
||||
else
|
||||
continue;
|
||||
if (area == GuildBankMainArea && slot < GUILD_BANK_MAIN_AREA_SIZE)
|
||||
itemSection = bank->Items.MainArea;
|
||||
else if (area != GuildBankMainArea && slot < GUILD_BANK_DEPOSIT_AREA_SIZE)
|
||||
itemSection = bank->Items.DepositArea;
|
||||
else
|
||||
continue;
|
||||
|
||||
itemSection[slot].ItemID = itemID;
|
||||
itemSection[slot].Quantity = qty;
|
||||
itemSection[slot].ItemID = itemID;
|
||||
itemSection[slot].Quantity = qty;
|
||||
|
||||
strn0cpy(itemSection[slot].Donator, donator, sizeof(donator));
|
||||
strn0cpy(itemSection[slot].Donator, donator, sizeof(donator));
|
||||
|
||||
itemSection[slot].Permissions = permissions;
|
||||
itemSection[slot].Permissions = permissions;
|
||||
|
||||
strn0cpy(itemSection[slot].WhoFor, whoFor, sizeof(whoFor));
|
||||
strn0cpy(itemSection[slot].WhoFor, whoFor, sizeof(whoFor));
|
||||
}
|
||||
|
||||
Banks.push_back(bank);
|
||||
@@ -666,7 +666,7 @@ bool GuildBankManager::Load(uint32 guildID)
|
||||
|
||||
bool GuildBankManager::IsLoaded(uint32 GuildID)
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
return (Iterator != Banks.end());
|
||||
}
|
||||
@@ -679,7 +679,7 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
if(!IsLoaded(c->GuildID()))
|
||||
Load(c->GuildID());
|
||||
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(c->GuildID());
|
||||
auto Iterator = GetGuildBank(c->GuildID());
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
{
|
||||
@@ -688,37 +688,94 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
return;
|
||||
}
|
||||
|
||||
auto &guild_bank = *Iterator;
|
||||
|
||||
// RoF+ uses a bulk list packet -- This is also how the Action 0 of older clients basically works
|
||||
if (c->ClientVersionBit() & EQEmu::versions::bit_RoFAndLater) {
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBankItemList, sizeof(GuildBankItemListEntry_Struct) * 240);
|
||||
for (int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i) {
|
||||
const EQEmu::ItemBase *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);
|
||||
if (Item) {
|
||||
outapp->WriteUInt8(1);
|
||||
outapp->WriteUInt32(guild_bank->Items.DepositArea[i].Permissions);
|
||||
outapp->WriteString(guild_bank->Items.DepositArea[i].WhoFor);
|
||||
outapp->WriteString(guild_bank->Items.DepositArea[i].Donator);
|
||||
outapp->WriteUInt32(Item->ID);
|
||||
outapp->WriteUInt32(Item->Icon);
|
||||
if (Item->Stackable) {
|
||||
outapp->WriteUInt32(guild_bank->Items.DepositArea[i].Quantity);
|
||||
outapp->WriteUInt8(Item->StackSize == guild_bank->Items.DepositArea[i].Quantity ? 0 : 1);
|
||||
} else {
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt8(0);
|
||||
}
|
||||
outapp->WriteUInt8(Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass()) ? 1 : 0);
|
||||
outapp->WriteString(Item->Name);
|
||||
} else {
|
||||
outapp->WriteUInt8(0); // empty
|
||||
}
|
||||
}
|
||||
outapp->SetWritePosition(outapp->GetWritePosition() + 20); // newer clients have 40 deposit slots, keep them 0 for now
|
||||
|
||||
for (int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i) {
|
||||
const EQEmu::ItemBase *Item = database.GetItem(guild_bank->Items.MainArea[i].ItemID);
|
||||
if (Item) {
|
||||
outapp->WriteUInt8(1);
|
||||
outapp->WriteUInt32(guild_bank->Items.MainArea[i].Permissions);
|
||||
outapp->WriteString(guild_bank->Items.MainArea[i].WhoFor);
|
||||
outapp->WriteString(guild_bank->Items.MainArea[i].Donator);
|
||||
outapp->WriteUInt32(Item->ID);
|
||||
outapp->WriteUInt32(Item->Icon);
|
||||
if (Item->Stackable) {
|
||||
outapp->WriteUInt32(guild_bank->Items.MainArea[i].Quantity);
|
||||
outapp->WriteUInt8(Item->StackSize == guild_bank->Items.MainArea[i].Quantity ? 0 : 1);
|
||||
} else {
|
||||
outapp->WriteUInt32(1);
|
||||
outapp->WriteUInt8(0);
|
||||
}
|
||||
outapp->WriteUInt8(Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass()) ? 1 : 0);
|
||||
outapp->WriteString(Item->Name);
|
||||
} else {
|
||||
outapp->WriteUInt8(0); // empty
|
||||
}
|
||||
}
|
||||
|
||||
outapp->size = outapp->GetWritePosition(); // truncate to used size
|
||||
c->FastQueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
|
||||
{
|
||||
if((*Iterator)->Items.DepositArea[i].ItemID > 0)
|
||||
if(guild_bank->Items.DepositArea[i].ItemID > 0)
|
||||
{
|
||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);
|
||||
|
||||
if(!Item)
|
||||
continue;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankItemUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankItemUpdate_Struct));
|
||||
|
||||
GuildBankItemUpdate_Struct *gbius = (GuildBankItemUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
if(!Item->Stackable)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon, 1,
|
||||
(*Iterator)->Items.DepositArea[i].Permissions, 0, 0);
|
||||
guild_bank->Items.DepositArea[i].Permissions, 0, 0);
|
||||
else
|
||||
{
|
||||
if((*Iterator)->Items.DepositArea[i].Quantity == Item->StackSize)
|
||||
if(guild_bank->Items.DepositArea[i].Quantity == Item->StackSize)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.DepositArea[i].Quantity, (*Iterator)->Items.DepositArea[i].Permissions, 0, 0);
|
||||
guild_bank->Items.DepositArea[i].Quantity, guild_bank->Items.DepositArea[i].Permissions, 0, 0);
|
||||
else
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.DepositArea[i].Quantity, (*Iterator)->Items.DepositArea[i].Permissions, 1, 0);
|
||||
guild_bank->Items.DepositArea[i].Quantity, guild_bank->Items.DepositArea[i].Permissions, 1, 0);
|
||||
}
|
||||
|
||||
strn0cpy(gbius->ItemName, Item->Name, sizeof(gbius->ItemName));
|
||||
|
||||
strn0cpy(gbius->Donator, (*Iterator)->Items.DepositArea[i].Donator, sizeof(gbius->Donator));
|
||||
strn0cpy(gbius->Donator, guild_bank->Items.DepositArea[i].Donator, sizeof(gbius->Donator));
|
||||
|
||||
strn0cpy(gbius->WhoFor, (*Iterator)->Items.DepositArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
strn0cpy(gbius->WhoFor, guild_bank->Items.DepositArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
|
||||
c->FastQueuePacket(&outapp);
|
||||
}
|
||||
@@ -726,37 +783,37 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
|
||||
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
||||
{
|
||||
if((*Iterator)->Items.MainArea[i].ItemID > 0)
|
||||
if(guild_bank->Items.MainArea[i].ItemID > 0)
|
||||
{
|
||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(guild_bank->Items.MainArea[i].ItemID);
|
||||
|
||||
if(!Item)
|
||||
continue;
|
||||
|
||||
bool Useable = Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass());
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankItemUpdate_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GuildBank, sizeof(GuildBankItemUpdate_Struct));
|
||||
|
||||
GuildBankItemUpdate_Struct *gbius = (GuildBankItemUpdate_Struct*)outapp->pBuffer;
|
||||
|
||||
if(!Item->Stackable)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon, 1,
|
||||
(*Iterator)->Items.MainArea[i].Permissions, 0, Useable);
|
||||
guild_bank->Items.MainArea[i].Permissions, 0, Useable);
|
||||
else
|
||||
{
|
||||
if((*Iterator)->Items.MainArea[i].Quantity == Item->StackSize)
|
||||
if(guild_bank->Items.MainArea[i].Quantity == Item->StackSize)
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.MainArea[i].Quantity, (*Iterator)->Items.MainArea[i].Permissions, 0, Useable);
|
||||
guild_bank->Items.MainArea[i].Quantity, guild_bank->Items.MainArea[i].Permissions, 0, Useable);
|
||||
else
|
||||
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||
(*Iterator)->Items.MainArea[i].Quantity, (*Iterator)->Items.MainArea[i].Permissions, 1, Useable);
|
||||
guild_bank->Items.MainArea[i].Quantity, guild_bank->Items.MainArea[i].Permissions, 1, Useable);
|
||||
}
|
||||
|
||||
strn0cpy(gbius->ItemName, Item->Name, sizeof(gbius->ItemName));
|
||||
|
||||
strn0cpy(gbius->Donator, (*Iterator)->Items.MainArea[i].Donator, sizeof(gbius->Donator));
|
||||
strn0cpy(gbius->Donator, guild_bank->Items.MainArea[i].Donator, sizeof(gbius->Donator));
|
||||
|
||||
strn0cpy(gbius->WhoFor, (*Iterator)->Items.MainArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
strn0cpy(gbius->WhoFor, guild_bank->Items.MainArea[i].WhoFor, sizeof(gbius->WhoFor));
|
||||
|
||||
c->FastQueuePacket(&outapp);
|
||||
}
|
||||
@@ -764,7 +821,7 @@ void GuildBankManager::SendGuildBank(Client *c)
|
||||
}
|
||||
bool GuildBankManager::IsAreaFull(uint32 GuildID, uint16 Area)
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
return true;
|
||||
@@ -795,7 +852,7 @@ bool GuildBankManager::IsAreaFull(uint32 GuildID, uint16 Area)
|
||||
|
||||
bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32 QtyOrCharges, const char *Donator, uint8 Permissions, const char *WhoFor)
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
{
|
||||
@@ -859,7 +916,7 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32
|
||||
return false;
|
||||
}
|
||||
|
||||
const Item_Struct *Item = database.GetItem(ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(ItemID);
|
||||
|
||||
GuildBankItemUpdate_Struct gbius;
|
||||
|
||||
@@ -925,7 +982,7 @@ int GuildBankManager::Promote(uint32 guildID, int slotID)
|
||||
|
||||
(*iter)->Items.DepositArea[slotID].ItemID = 0;
|
||||
|
||||
const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID);
|
||||
|
||||
GuildBankItemUpdate_Struct gbius;
|
||||
|
||||
@@ -981,7 +1038,7 @@ void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 perm
|
||||
else
|
||||
(*iter)->Items.MainArea[slotID].WhoFor[0] = '\0';
|
||||
|
||||
const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID);
|
||||
|
||||
GuildBankItemUpdate_Struct gbius;
|
||||
|
||||
@@ -1007,7 +1064,7 @@ void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 perm
|
||||
|
||||
ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity)
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
return nullptr;
|
||||
@@ -1057,7 +1114,7 @@ ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID,
|
||||
|
||||
bool GuildBankManager::HasItem(uint32 GuildID, uint32 ItemID)
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
return false;
|
||||
@@ -1075,7 +1132,7 @@ bool GuildBankManager::HasItem(uint32 GuildID, uint32 ItemID)
|
||||
|
||||
std::list<GuildBank*>::iterator GuildBankManager::GetGuildBank(uint32 GuildID)
|
||||
{
|
||||
std::list<GuildBank*>::iterator Iterator = Banks.begin();
|
||||
auto Iterator = Banks.begin();
|
||||
|
||||
while(Iterator != Banks.end())
|
||||
{
|
||||
@@ -1112,7 +1169,7 @@ bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, ui
|
||||
|
||||
bool deleted = true;
|
||||
|
||||
const Item_Struct *Item = database.GetItem(BankArea[slotID].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(BankArea[slotID].ItemID);
|
||||
|
||||
if(!Item->Stackable || (quantity >= BankArea[slotID].Quantity)) {
|
||||
std::string query = StringFormat("DELETE FROM `guild_bank` WHERE `guildid` = %i "
|
||||
@@ -1163,7 +1220,7 @@ bool GuildBankManager::MergeStacks(uint32 GuildID, uint16 SlotID)
|
||||
if(SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))
|
||||
return false;
|
||||
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
return false;
|
||||
@@ -1173,7 +1230,7 @@ bool GuildBankManager::MergeStacks(uint32 GuildID, uint16 SlotID)
|
||||
if(BankArea[SlotID].ItemID == 0)
|
||||
return false;
|
||||
|
||||
const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
|
||||
if(!Item->Stackable)
|
||||
return false;
|
||||
@@ -1255,7 +1312,7 @@ bool GuildBankManager::SplitStack(uint32 GuildID, uint16 SlotID, uint32 Quantity
|
||||
if(SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))
|
||||
return false;
|
||||
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
return false;
|
||||
@@ -1271,7 +1328,7 @@ bool GuildBankManager::SplitStack(uint32 GuildID, uint16 SlotID, uint32 Quantity
|
||||
if(BankArea[SlotID].Quantity <= Quantity || Quantity == 0)
|
||||
return false;
|
||||
|
||||
const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
const EQEmu::ItemBase *Item = database.GetItem(BankArea[SlotID].ItemID);
|
||||
|
||||
if(!Item->Stackable)
|
||||
return false;
|
||||
@@ -1306,7 +1363,7 @@ bool GuildBankManager::AllowedToWithdraw(uint32 GuildID, uint16 Area, uint16 Slo
|
||||
if(SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))
|
||||
return false;
|
||||
|
||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
||||
auto Iterator = GetGuildBank(GuildID);
|
||||
|
||||
if(Iterator == Banks.end())
|
||||
return false;
|
||||
@@ -1349,8 +1406,9 @@ bool GuildApproval::ProcessApproval()
|
||||
|
||||
GuildApproval::GuildApproval(const char* guildname, Client* owner,uint32 id)
|
||||
{
|
||||
database.GetVariable("GuildCreation", founders, 3);
|
||||
uint8 tmp = atoi(founders);
|
||||
std::string founders;
|
||||
database.GetVariable("GuildCreation", founders);
|
||||
uint8 tmp = atoi(founders.c_str());
|
||||
deletion_timer = new Timer(1800000);
|
||||
strcpy(guild,guildname);
|
||||
this->owner = owner;
|
||||
@@ -1368,8 +1426,9 @@ GuildApproval::~GuildApproval()
|
||||
|
||||
bool GuildApproval::AddMemberApproval(Client* addition)
|
||||
{
|
||||
database.GetVariable("GuildCreation", founders, 3);
|
||||
uint8 tmp = atoi(founders);
|
||||
std::string founders;
|
||||
database.GetVariable("GuildCreation", founders);
|
||||
uint8 tmp = atoi(founders.c_str());
|
||||
for(int i=0;i<tmp;i++)
|
||||
{
|
||||
if(members[i] && members[i] == addition)
|
||||
@@ -1398,8 +1457,9 @@ bool GuildApproval::AddMemberApproval(Client* addition)
|
||||
|
||||
void GuildApproval::ApprovedMembers(Client* requestee)
|
||||
{
|
||||
database.GetVariable("GuildCreation", founders, 3);
|
||||
uint8 tmp = atoi(founders);
|
||||
std::string founders;
|
||||
database.GetVariable("GuildCreation", founders);
|
||||
uint8 tmp = atoi(founders.c_str());
|
||||
for(int i=0;i<tmp;i++)
|
||||
{
|
||||
if(members[i])
|
||||
@@ -1414,8 +1474,9 @@ void GuildApproval::GuildApproved()
|
||||
|
||||
if(!owner)
|
||||
return;
|
||||
database.GetVariable("GuildCreation", founders, 3);
|
||||
uint8 tmp = atoi(founders);
|
||||
std::string founders;
|
||||
database.GetVariable("GuildCreation", founders);
|
||||
uint8 tmp = atoi(founders.c_str());
|
||||
uint32 tmpeq = guild_mgr.CreateGuild(guild, owner->CharacterID());
|
||||
guild_mgr.SetGuild(owner->CharacterID(),tmpeq,2);
|
||||
owner->SendAppearancePacket(AT_GuildID,true,false);
|
||||
@@ -1437,7 +1498,7 @@ void GuildApproval::GuildApproved()
|
||||
strncat(petitext,owner->CastToClient()->GetName(),len);
|
||||
strncat(petitext," Members:",len);
|
||||
strncat(petitext,gmembers,len);
|
||||
Petition* pet = new Petition(owner->CastToClient()->CharacterID());
|
||||
auto pet = new Petition(owner->CastToClient()->CharacterID());
|
||||
pet->SetAName(owner->CastToClient()->AccountName());
|
||||
pet->SetClass(owner->CastToClient()->GetClass());
|
||||
pet->SetLevel(owner->CastToClient()->GetLevel());
|
||||
@@ -1453,7 +1514,7 @@ void GuildApproval::GuildApproved()
|
||||
petition_list.UpdateGMQueue();
|
||||
petition_list.UpdateZoneListQueue();
|
||||
worldserver.SendEmoteMessage(0, 0, 80, 15, "%s has made a petition. #%i", owner->CastToClient()->GetName(), pet->GetID());
|
||||
ServerPacket* pack = new ServerPacket;
|
||||
auto pack = new ServerPacket;
|
||||
pack->opcode = ServerOP_RefreshGuild;
|
||||
pack->size = tmp;
|
||||
pack->pBuffer = new uchar[pack->size];
|
||||
|
||||
@@ -61,7 +61,6 @@ public:
|
||||
private:
|
||||
Timer* deletion_timer;
|
||||
char guild[16];
|
||||
char founders[3];
|
||||
Client* owner;
|
||||
Client* members[6];
|
||||
uint32 refid;
|
||||
|
||||
+22
-30
@@ -67,8 +67,10 @@ void HateList::WipeHateList()
|
||||
{
|
||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), m, "0", 0);
|
||||
|
||||
if (m->IsClient())
|
||||
if (m->IsClient()) {
|
||||
m->CastToClient()->DecrementAggroCount();
|
||||
m->CastToClient()->RemoveXTarget(hate_owner, true);
|
||||
}
|
||||
}
|
||||
delete (*iterator);
|
||||
iterator = list.erase(iterator);
|
||||
@@ -535,37 +537,27 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
|
||||
if (!target || !caster)
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
std::list<uint32> id_list;
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end())
|
||||
{
|
||||
struct_HateList *h = (*iterator);
|
||||
++iterator;
|
||||
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster)
|
||||
{
|
||||
if (caster->CombatRange(h->entity_on_hatelist))
|
||||
{
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
++ret;
|
||||
}
|
||||
int hit_count = 0;
|
||||
// This should prevent crashes if something dies (or mainly more than 1 thing goes away)
|
||||
// This is a temp solution until the hate lists can be rewritten to not have that issue
|
||||
std::vector<uint16> id_list;
|
||||
for (auto &h : list) {
|
||||
if (h->entity_on_hatelist && h->entity_on_hatelist != caster &&
|
||||
caster->CombatRange(h->entity_on_hatelist))
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
if (count != -1 && id_list.size() > count)
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto &id : id_list) {
|
||||
auto mob = entity_list.GetMobID(id);
|
||||
if (mob) {
|
||||
++hit_count;
|
||||
caster->ProcessAttackRounds(mob, opts, 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::list<uint32>::iterator iter = id_list.begin();
|
||||
while (iter != id_list.end())
|
||||
{
|
||||
Mob *cur = entity_list.GetMobID((*iter));
|
||||
if (cur)
|
||||
{
|
||||
for (int i = 0; i < count; ++i) {
|
||||
caster->Attack(cur, MainPrimary, false, false, false, opts);
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return hit_count;
|
||||
}
|
||||
|
||||
void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center)
|
||||
@@ -607,7 +599,7 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_cent
|
||||
++iterator;
|
||||
}
|
||||
|
||||
std::list<uint32>::iterator iter = id_list.begin();
|
||||
auto iter = id_list.begin();
|
||||
while (iter != id_list.end())
|
||||
{
|
||||
Mob *cur = entity_list.GetMobID((*iter));
|
||||
|
||||
@@ -0,0 +1,950 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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
|
||||
*/
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
#include "bot.h"
|
||||
|
||||
#define SAFE_HP_RATIO_CLOTH 95.0f
|
||||
#define SAFE_HP_RATIO_LEATHER 90.0f
|
||||
#define SAFE_HP_RATIO_CHAIN 80.0f
|
||||
#define SAFE_HP_RATIO_PLATE 75.0f
|
||||
|
||||
#define CRITICAL_HP_RATIO_CLOTH 45.0f
|
||||
#define CRITICAL_HP_RATIO_LEATHER 40.0f
|
||||
#define CRITICAL_HP_RATIO_CHAIN 35.0f
|
||||
#define CRITICAL_HP_RATIO_PLATE 30.0f
|
||||
|
||||
HealRotation::HealRotation(Bot* hr_creator, uint32 interval_ms, bool fast_heals, bool adaptive_targeting, bool casting_override)
|
||||
{
|
||||
m_member_pool.push_back(hr_creator);
|
||||
|
||||
m_creation_time_ms = Timer::GetCurrentTime();
|
||||
m_last_heal_time_ms = m_creation_time_ms;
|
||||
m_interval_ms = ((interval_ms >= CASTING_CYCLE_MINIMUM_INTERVAL) ? (interval_ms) : (CASTING_CYCLE_MINIMUM_INTERVAL));
|
||||
m_next_cast_time_ms = m_creation_time_ms;
|
||||
m_next_poke_time_ms = m_creation_time_ms;
|
||||
m_healing_stats_begin_ms = m_creation_time_ms;
|
||||
m_fast_heals = fast_heals;
|
||||
m_adaptive_targeting = adaptive_targeting;
|
||||
m_casting_override = casting_override;
|
||||
m_casting_target_poke = true;
|
||||
m_active_heal_target = false;
|
||||
|
||||
ResetArmorTypeHPLimits();
|
||||
|
||||
m_is_active = false;
|
||||
|
||||
m_consumed = false;
|
||||
|
||||
m_hot_target = nullptr;
|
||||
m_hot_active = false;
|
||||
}
|
||||
|
||||
void HealRotation::SetIntervalMS(uint32 interval_ms)
|
||||
{
|
||||
if (interval_ms > CASTING_CYCLE_MAXIMUM_INTERVAL)
|
||||
interval_ms = CASTING_CYCLE_MAXIMUM_INTERVAL;
|
||||
else if (interval_ms < CASTING_CYCLE_MINIMUM_INTERVAL)
|
||||
interval_ms = CASTING_CYCLE_MINIMUM_INTERVAL;
|
||||
|
||||
m_interval_ms = interval_ms;
|
||||
}
|
||||
|
||||
void HealRotation::SetIntervalS(uint32 interval_s)
|
||||
{
|
||||
interval_s *= 1000;
|
||||
if (interval_s > CASTING_CYCLE_MAXIMUM_INTERVAL)
|
||||
interval_s = CASTING_CYCLE_MAXIMUM_INTERVAL;
|
||||
else if (interval_s < CASTING_CYCLE_MINIMUM_INTERVAL)
|
||||
interval_s = CASTING_CYCLE_MINIMUM_INTERVAL;
|
||||
|
||||
m_interval_ms = interval_s;
|
||||
}
|
||||
|
||||
bool HealRotation::AddMemberToPool(Bot* hr_member)
|
||||
{
|
||||
if (!hr_member)
|
||||
return false;
|
||||
if (!IsHealRotationMemberClass(hr_member->GetClass()))
|
||||
return false;
|
||||
if (m_member_pool.size() >= RuleI(Bots, HealRotationMaxMembers))
|
||||
return false;
|
||||
|
||||
for (auto find_iter : m_member_pool) {
|
||||
if (find_iter == hr_member)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_member_pool.push_back(hr_member);
|
||||
valid_state();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::AddTargetToPool(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return false;
|
||||
if (!valid_state())
|
||||
return false;
|
||||
if (!IsHealRotationTargetMobType(hr_target))
|
||||
return false;
|
||||
if (m_target_pool.size() >= RuleI(Bots, HealRotationMaxTargets))
|
||||
return false;
|
||||
|
||||
for (auto find_iter : m_target_pool) {
|
||||
if (find_iter == hr_target)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_target_pool.push_back(hr_target);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::RemoveMemberFromPool(Bot* hr_member)
|
||||
{
|
||||
if (!hr_member)
|
||||
return true;
|
||||
|
||||
for (auto member_iter : m_member_pool) {
|
||||
if (member_iter != hr_member)
|
||||
continue;
|
||||
|
||||
m_member_is_casting.erase(hr_member);
|
||||
m_member_pool.remove(hr_member);
|
||||
valid_state();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HealRotation::RemoveTargetFromPool(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return true;
|
||||
if (!valid_state())
|
||||
return true;
|
||||
|
||||
for (auto target_iter : m_target_pool) {
|
||||
if (target_iter != hr_target)
|
||||
continue;
|
||||
|
||||
if (m_hot_target == hr_target) {
|
||||
m_hot_target = nullptr;
|
||||
m_hot_active = false;
|
||||
}
|
||||
|
||||
m_target_healing_stats_2.erase(hr_target);
|
||||
m_target_healing_stats_1.erase(hr_target);
|
||||
m_target_pool.remove(hr_target);
|
||||
m_casting_target_poke = false;
|
||||
bias_targets();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HealRotation::ClearMemberPool()
|
||||
{
|
||||
m_is_active = false;
|
||||
m_cycle_pool.clear();
|
||||
m_casting_target_poke = false;
|
||||
m_active_heal_target = false;
|
||||
|
||||
ClearTargetPool();
|
||||
|
||||
auto clear_list = m_member_pool;
|
||||
for (auto member_iter : clear_list)
|
||||
member_iter->LeaveHealRotationMemberPool();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::ClearTargetPool()
|
||||
{
|
||||
m_hot_target = nullptr;
|
||||
m_hot_active = false;
|
||||
m_is_active = false;
|
||||
|
||||
auto clear_list = m_target_pool;
|
||||
for (auto target_iter : clear_list)
|
||||
target_iter->LeaveHealRotationTargetPool();
|
||||
|
||||
m_casting_target_poke = false;
|
||||
bias_targets();
|
||||
|
||||
return m_target_pool.empty();
|
||||
}
|
||||
|
||||
bool HealRotation::SetHOTTarget(Mob* hot_target)
|
||||
{
|
||||
if (!hot_target || !IsTargetInPool(hot_target))
|
||||
return false;
|
||||
|
||||
m_hot_target = hot_target;
|
||||
m_hot_active = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::ClearHOTTarget()
|
||||
{
|
||||
m_hot_target = nullptr;
|
||||
m_hot_active = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::Start()
|
||||
{
|
||||
m_is_active = false;
|
||||
if (m_member_pool.empty() || m_target_pool.empty()) {
|
||||
validate_hot();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cycle_pool = m_member_pool;
|
||||
m_is_active = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::Stop()
|
||||
{
|
||||
m_is_active = false;
|
||||
m_active_heal_target = false;
|
||||
m_cycle_pool.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Bot* HealRotation::CastingMember()
|
||||
{
|
||||
if (!m_is_active && !m_hot_active)
|
||||
return nullptr;
|
||||
|
||||
if (m_cycle_pool.empty()) {
|
||||
cycle_refresh();
|
||||
|
||||
if (m_cycle_pool.empty())
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_cycle_pool.front();
|
||||
}
|
||||
|
||||
bool HealRotation::PokeCastingTarget()
|
||||
{
|
||||
if (m_hot_target && m_hot_active)
|
||||
return true;
|
||||
|
||||
if (!m_is_active)
|
||||
return false;
|
||||
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
|
||||
if (current_time < m_next_poke_time_ms) {
|
||||
auto hr_target = CastingTarget();
|
||||
if (hr_target && hr_target->DontHealMeBefore() > current_time)
|
||||
m_next_poke_time_ms = current_time;
|
||||
else
|
||||
return m_active_heal_target;
|
||||
}
|
||||
|
||||
m_next_poke_time_ms = (current_time + POKE_PROPAGATION_DELAY);
|
||||
|
||||
if (m_healing_stats_begin_ms + HEALING_STATS_RESET_INTERVAL <= current_time)
|
||||
StartNewTargetHealingStatsCycle(current_time);
|
||||
|
||||
m_casting_target_poke = false;
|
||||
bias_targets();
|
||||
|
||||
return m_active_heal_target;
|
||||
}
|
||||
|
||||
Mob* HealRotation::CastingTarget()
|
||||
{
|
||||
if (m_hot_target && m_hot_active)
|
||||
return m_hot_target;
|
||||
|
||||
if (!m_is_active)
|
||||
return nullptr;
|
||||
if (!m_active_heal_target)
|
||||
return nullptr;
|
||||
|
||||
return m_target_pool.front();
|
||||
}
|
||||
|
||||
bool HealRotation::AdvanceRotation(bool use_interval)
|
||||
{
|
||||
m_cycle_pool.pop_front();
|
||||
m_next_cast_time_ms = Timer::GetCurrentTime();
|
||||
if (use_interval) {
|
||||
m_next_poke_time_ms = m_next_cast_time_ms;
|
||||
m_next_cast_time_ms += m_interval_ms;
|
||||
}
|
||||
else {
|
||||
m_next_cast_time_ms += ADVANCE_ROTATION_MINIMUM_INTERVAL;
|
||||
}
|
||||
|
||||
if (m_cycle_pool.empty())
|
||||
cycle_refresh();
|
||||
|
||||
return (!m_cycle_pool.empty());
|
||||
}
|
||||
|
||||
bool HealRotation::IsMemberInPool(Bot* hr_member)
|
||||
{
|
||||
if (!hr_member)
|
||||
return false;
|
||||
if (m_member_pool.empty())
|
||||
return false;
|
||||
|
||||
for (auto find_iter : m_member_pool) {
|
||||
if (find_iter == hr_member)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HealRotation::IsTargetInPool(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return false;
|
||||
if (m_target_pool.empty())
|
||||
return false;
|
||||
|
||||
for (auto find_iter : m_target_pool) {
|
||||
if (find_iter == hr_target)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HealRotation::IsHOTTarget(Mob* hot_target)
|
||||
{
|
||||
if (!hot_target)
|
||||
return false;
|
||||
if (m_hot_target != hot_target)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HealRotation::SetMemberIsCasting(Bot* hr_member, bool flag)
|
||||
{
|
||||
if (!hr_member)
|
||||
return;
|
||||
if (!IsMemberInPool(hr_member))
|
||||
return;
|
||||
|
||||
m_member_is_casting[hr_member] = flag;
|
||||
}
|
||||
|
||||
bool HealRotation::MemberIsCasting(Bot* hr_member)
|
||||
{
|
||||
if (!hr_member)
|
||||
return false;
|
||||
if (m_member_is_casting.find(hr_member) == m_member_is_casting.end())
|
||||
return false;
|
||||
|
||||
return m_member_is_casting[hr_member];
|
||||
}
|
||||
|
||||
void HealRotation::UpdateTargetHealingStats(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return;
|
||||
if (!IsTargetInPool(hr_target))
|
||||
return;
|
||||
|
||||
m_last_heal_time_ms = Timer::GetCurrentTime();
|
||||
|
||||
m_target_healing_stats_1[hr_target].last_heal_time_ms = m_last_heal_time_ms;
|
||||
++m_target_healing_stats_1[hr_target].heal_count;
|
||||
}
|
||||
|
||||
void HealRotation::StartNewTargetHealingStatsCycle(uint32 current_time)
|
||||
{
|
||||
m_target_healing_stats_2 = m_target_healing_stats_1;
|
||||
m_target_healing_stats_1.clear();
|
||||
|
||||
m_healing_stats_begin_ms = current_time;
|
||||
}
|
||||
|
||||
uint32 HealRotation::HealCount(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return 0;
|
||||
|
||||
uint32 heal_count = 0;
|
||||
if (m_target_healing_stats_1.find(hr_target) != m_target_healing_stats_1.end())
|
||||
heal_count += m_target_healing_stats_1[hr_target].heal_count;
|
||||
|
||||
return heal_count;
|
||||
}
|
||||
|
||||
uint32 HealRotation::ExtendedHealCount(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return 0;
|
||||
|
||||
uint32 heal_count = 0;
|
||||
if (m_target_healing_stats_1.find(hr_target) != m_target_healing_stats_1.end())
|
||||
heal_count += m_target_healing_stats_1[hr_target].heal_count;
|
||||
if (m_target_healing_stats_2.find(hr_target) != m_target_healing_stats_2.end())
|
||||
heal_count += m_target_healing_stats_2[hr_target].heal_count;
|
||||
|
||||
return heal_count;
|
||||
}
|
||||
|
||||
float HealRotation::HealFrequency(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return 0.0f;
|
||||
|
||||
float time_base = 0;
|
||||
uint32 heal_count = 0;
|
||||
if (m_target_healing_stats_1.find(hr_target) != m_target_healing_stats_1.end()) {
|
||||
heal_count += m_target_healing_stats_1[hr_target].heal_count;
|
||||
time_base = (Timer::GetCurrentTime() - m_target_healing_stats_1[hr_target].last_heal_time_ms);
|
||||
}
|
||||
|
||||
time_base /= 1000;
|
||||
if (!time_base)
|
||||
time_base = HEALING_STATS_RESET_INTERVAL_S;
|
||||
|
||||
if (heal_count)
|
||||
return ((float)1 / (time_base / heal_count));
|
||||
else
|
||||
return ((float)1 / time_base);
|
||||
}
|
||||
|
||||
float HealRotation::ExtendedHealFrequency(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return 0.0f;
|
||||
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
uint32 heal_count = 0;
|
||||
float time_base = 0;
|
||||
if (m_target_healing_stats_1.find(hr_target) != m_target_healing_stats_1.end()) {
|
||||
heal_count += m_target_healing_stats_1[hr_target].heal_count;
|
||||
time_base = (current_time - m_target_healing_stats_1[hr_target].last_heal_time_ms + HEALING_STATS_RESET_INTERVAL);
|
||||
}
|
||||
if (m_target_healing_stats_2.find(hr_target) != m_target_healing_stats_2.end()) {
|
||||
heal_count += m_target_healing_stats_2[hr_target].heal_count;
|
||||
time_base = (current_time - m_target_healing_stats_2[hr_target].last_heal_time_ms);
|
||||
}
|
||||
|
||||
time_base /= 1000;
|
||||
if (!time_base)
|
||||
time_base = (HEALING_STATS_RESET_INTERVAL_S * 2);
|
||||
|
||||
if (heal_count)
|
||||
return ((float)1 / (time_base / heal_count));
|
||||
else
|
||||
return ((float)1 / time_base);
|
||||
}
|
||||
|
||||
HealingStats* HealRotation::TargetHealingStats1(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return nullptr;
|
||||
if (m_target_healing_stats_1.find(hr_target) == m_target_healing_stats_1.end())
|
||||
return nullptr;
|
||||
|
||||
return &m_target_healing_stats_1[hr_target];
|
||||
}
|
||||
|
||||
HealingStats* HealRotation::TargetHealingStats2(Mob* hr_target)
|
||||
{
|
||||
if (!hr_target)
|
||||
return nullptr;
|
||||
if (m_target_healing_stats_2.find(hr_target) == m_target_healing_stats_2.end())
|
||||
return nullptr;
|
||||
|
||||
return &m_target_healing_stats_2[hr_target];
|
||||
}
|
||||
|
||||
bool HealRotation::SetArmorTypeSafeHPRatio(uint8 armor_type, float hp_ratio)
|
||||
{
|
||||
if (armor_type >= ARMOR_TYPE_COUNT)
|
||||
return false;
|
||||
if (hp_ratio < CRITICAL_HP_RATIO_ABS || hp_ratio > SAFE_HP_RATIO_ABS)
|
||||
return false;
|
||||
if (hp_ratio < m_critical_hp_ratio[armor_type])
|
||||
return false;
|
||||
|
||||
m_safe_hp_ratio[armor_type] = hp_ratio;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HealRotation::SetArmorTypeCriticalHPRatio(uint8 armor_type, float hp_ratio)
|
||||
{
|
||||
if (armor_type >= ARMOR_TYPE_COUNT)
|
||||
return false;
|
||||
if (hp_ratio < CRITICAL_HP_RATIO_ABS || hp_ratio > SAFE_HP_RATIO_ABS)
|
||||
return false;
|
||||
if (hp_ratio > m_safe_hp_ratio[armor_type])
|
||||
return false;
|
||||
|
||||
m_critical_hp_ratio[armor_type] = hp_ratio;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float HealRotation::ArmorTypeSafeHPRatio(uint8 armor_type)
|
||||
{
|
||||
if (armor_type < ARMOR_TYPE_COUNT)
|
||||
return m_safe_hp_ratio[armor_type];
|
||||
else
|
||||
return m_safe_hp_ratio[ARMOR_TYPE_UNKNOWN];
|
||||
}
|
||||
|
||||
float HealRotation::ArmorTypeCriticalHPRatio(uint8 armor_type)
|
||||
{
|
||||
if (armor_type < ARMOR_TYPE_COUNT)
|
||||
return m_critical_hp_ratio[armor_type];
|
||||
else
|
||||
return m_critical_hp_ratio[ARMOR_TYPE_UNKNOWN];
|
||||
}
|
||||
|
||||
void HealRotation::ResetArmorTypeHPLimits()
|
||||
{
|
||||
m_safe_hp_ratio[ARMOR_TYPE_UNKNOWN] = SAFE_HP_RATIO_BASE;
|
||||
m_safe_hp_ratio[ARMOR_TYPE_CLOTH] = SAFE_HP_RATIO_CLOTH;
|
||||
m_safe_hp_ratio[ARMOR_TYPE_LEATHER] = SAFE_HP_RATIO_LEATHER;
|
||||
m_safe_hp_ratio[ARMOR_TYPE_CHAIN] = SAFE_HP_RATIO_CHAIN;
|
||||
m_safe_hp_ratio[ARMOR_TYPE_PLATE] = SAFE_HP_RATIO_PLATE;
|
||||
|
||||
m_critical_hp_ratio[ARMOR_TYPE_UNKNOWN] = CRITICAL_HP_RATIO_BASE;
|
||||
m_critical_hp_ratio[ARMOR_TYPE_CLOTH] = CRITICAL_HP_RATIO_CLOTH;
|
||||
m_critical_hp_ratio[ARMOR_TYPE_LEATHER] = CRITICAL_HP_RATIO_LEATHER;
|
||||
m_critical_hp_ratio[ARMOR_TYPE_CHAIN] = CRITICAL_HP_RATIO_CHAIN;
|
||||
m_critical_hp_ratio[ARMOR_TYPE_PLATE] = CRITICAL_HP_RATIO_PLATE;
|
||||
}
|
||||
|
||||
bool HealRotation::valid_state()
|
||||
{
|
||||
m_member_pool.remove(nullptr);
|
||||
m_member_pool.remove_if([](Mob* l) {return (!IsHealRotationMemberClass(l->GetClass())); });
|
||||
|
||||
cycle_refresh();
|
||||
|
||||
if (m_member_pool.empty() && !m_consumed) { // Consumes HealRotation at this point
|
||||
m_consumed = true;
|
||||
ClearTargetPool();
|
||||
}
|
||||
|
||||
return (!m_member_pool.empty());
|
||||
}
|
||||
|
||||
void HealRotation::cycle_refresh()
|
||||
{
|
||||
m_is_active = false;
|
||||
m_cycle_pool.clear();
|
||||
if (m_member_pool.empty())
|
||||
return;
|
||||
|
||||
m_cycle_pool = m_member_pool;
|
||||
|
||||
m_is_active = true;
|
||||
}
|
||||
|
||||
bool HealRotation::healable_target(bool use_class_at, bool critical_only)
|
||||
{
|
||||
if (m_target_pool.empty())
|
||||
return false;
|
||||
|
||||
auto healable_target = m_target_pool.front();
|
||||
if (!healable_target)
|
||||
return false;
|
||||
if (healable_target->DontHealMeBefore() > Timer::GetCurrentTime())
|
||||
return false;
|
||||
if (healable_target->GetAppearance() == eaDead)
|
||||
return false;
|
||||
|
||||
if (use_class_at) {
|
||||
if (critical_only && healable_target->GetHPRatio() > m_critical_hp_ratio[ClassArmorType(healable_target->GetClass())])
|
||||
return false;
|
||||
if (healable_target->GetHPRatio() > m_safe_hp_ratio[ClassArmorType(healable_target->GetClass())])
|
||||
return false;
|
||||
if (healable_target->IsBerserk() && (healable_target->GetClass() == WARRIOR || healable_target->GetClass() == BERSERKER)) {
|
||||
if (healable_target->GetHPRatio() <= RuleI(Combat, BerserkerFrenzyEnd) && healable_target->GetHPRatio() > m_critical_hp_ratio[ClassArmorType(healable_target->GetClass())])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (critical_only && healable_target->GetHPRatio() > CRITICAL_HP_RATIO_BASE)
|
||||
return false;
|
||||
if (healable_target->GetHPRatio() > SAFE_HP_RATIO_BASE)
|
||||
return false;
|
||||
if (healable_target->IsBerserk() && (healable_target->GetClass() == WARRIOR || healable_target->GetClass() == BERSERKER)) {
|
||||
if (healable_target->GetHPRatio() <= RuleI(Combat, BerserkerFrenzyEnd) && healable_target->GetHPRatio() > CRITICAL_HP_RATIO_BASE)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HealRotation::bias_targets()
|
||||
{
|
||||
#define LT_HPRATIO(l, r) (l->GetHPRatio() < r->GetHPRatio())
|
||||
#define LT_ARMTYPE(l, r) (ClassArmorType(l->GetClass()) < ClassArmorType(r->GetClass()))
|
||||
|
||||
#define EQ_ALIVE(l, r) (l->GetAppearance() != eaDead && r->GetAppearance() != eaDead)
|
||||
#define EQ_READY(l, r, ct) (l->DontHealMeBefore() <= ct && r->DontHealMeBefore() <= ct)
|
||||
#define EQ_TANK(l, r) ((l->HasGroup() && l->GetGroup()->AmIMainTank(l->GetCleanName())) && (r->HasGroup() && r->GetGroup()->AmIMainTank(r->GetCleanName())))
|
||||
#define EQ_HEALER(l, r) (IsHealRotationMemberClass(l->GetClass()) && IsHealRotationMemberClass(r->GetClass()))
|
||||
#define EQ_ARMTYPE(l, r) (ClassArmorType(l->GetClass()) == ClassArmorType(r->GetClass()))
|
||||
#define EQ_ATCRIT(l, r) (l->GetHPRatio() <= (*l->TargetOfHealRotation())->ArmorTypeCriticalHPRatio(ClassArmorType(l->GetClass())) && \
|
||||
r->GetHPRatio() <= (*r->TargetOfHealRotation())->ArmorTypeCriticalHPRatio(ClassArmorType(r->GetClass())))
|
||||
#define EQ_ATWOUND(l, r) (l->GetHPRatio() <= (*l->TargetOfHealRotation())->ArmorTypeSafeHPRatio(ClassArmorType(l->GetClass())) && \
|
||||
r->GetHPRatio() <= (*r->TargetOfHealRotation())->ArmorTypeSafeHPRatio(ClassArmorType(r->GetClass())))
|
||||
|
||||
#define GT_ALIVE(l, r) (l->GetAppearance() != eaDead && r->GetAppearance() == eaDead)
|
||||
#define GT_READY(l, r, ct) (l->DontHealMeBefore() <= ct && r->DontHealMeBefore() > ct)
|
||||
#define GT_TANK(l, r) ((l->HasGroup() && l->GetGroup()->AmIMainTank(l->GetCleanName())) && (!r->HasGroup() || !r->GetGroup()->AmIMainTank(r->GetCleanName())))
|
||||
#define GT_HEALER(l, r) (IsHealRotationMemberClass(l->GetClass()) && !IsHealRotationMemberClass(r->GetClass()))
|
||||
#define GT_HEALFREQ(l, r) (l->HealRotationHealFrequency() > r->HealRotationHealFrequency())
|
||||
#define GT_HEALCNT(l, r) (l->HealRotationHealCount() > r->HealRotationHealCount())
|
||||
#define GT_ATCRIT(l, r) (l->GetHPRatio() <= (*l->TargetOfHealRotation())->ArmorTypeCriticalHPRatio(ClassArmorType(l->GetClass())) && \
|
||||
r->GetHPRatio() > (*r->TargetOfHealRotation())->ArmorTypeCriticalHPRatio(ClassArmorType(r->GetClass())))
|
||||
#define GT_XHEALFREQ(l, r) (l->HealRotationExtendedHealFrequency() > r->HealRotationExtendedHealFrequency())
|
||||
#define GT_XHEALCNT(l, r) (l->HealRotationExtendedHealCount() > r->HealRotationExtendedHealCount())
|
||||
#define GT_ATWOUND(l, r) (l->GetHPRatio() <= (*l->TargetOfHealRotation())->ArmorTypeSafeHPRatio(ClassArmorType(l->GetClass())) && \
|
||||
r->GetHPRatio() > (*r->TargetOfHealRotation())->ArmorTypeSafeHPRatio(ClassArmorType(r->GetClass())))
|
||||
|
||||
if (m_target_pool.empty()) {
|
||||
m_casting_target_poke = true;
|
||||
m_active_heal_target = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// attempt to clear invalid target pool entries
|
||||
m_target_pool.remove(nullptr);
|
||||
m_target_pool.remove_if([](Mob* l) { return (!IsHealRotationTargetMobType(l)); });
|
||||
|
||||
uint32 sort_type = 0; // debug
|
||||
|
||||
while (m_target_pool.size() > 1 && !m_casting_target_poke && !m_adaptive_targeting) { // standard behavior
|
||||
sort_type = 1;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_TANK(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_TANK(l, r) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (m_target_pool.front()->HasGroup() && m_target_pool.front()->GetGroup()->AmIMainTank(m_target_pool.front()->GetCleanName()) && healable_target(false))
|
||||
break;
|
||||
|
||||
sort_type = 2;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_HEALER(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_HEALER(l, r) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (IsHealRotationMemberClass(m_target_pool.front()->GetClass()) && healable_target(false))
|
||||
break;
|
||||
|
||||
sort_type = 3; // default
|
||||
m_target_pool.sort([](const Mob* l, const Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
while (m_target_pool.size() > 1 && !m_casting_target_poke && m_adaptive_targeting) { // adaptive targeting behavior
|
||||
sort_type = 101;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_HEALFREQ(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (healable_target(true, true))
|
||||
break;
|
||||
|
||||
sort_type = 102;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_HEALCNT(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (healable_target(true, true))
|
||||
break;
|
||||
|
||||
sort_type = 103;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_TANK(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_TANK(l, r) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (m_target_pool.front()->HasGroup() && m_target_pool.front()->GetGroup()->AmIMainTank(m_target_pool.front()->GetCleanName()) && healable_target(true, true))
|
||||
break;
|
||||
|
||||
sort_type = 104;
|
||||
m_target_pool.sort([](const Mob* l, const Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_HEALER(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_HEALER(l, r) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (IsHealRotationMemberClass(m_target_pool.front()->GetClass()) && healable_target(true, true))
|
||||
break;
|
||||
|
||||
sort_type = 105;
|
||||
m_target_pool.sort([](const Mob* l, const Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_ATCRIT(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_ATCRIT(l, r) && LT_ARMTYPE(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_ATCRIT(l, r) && EQ_ARMTYPE(l, r) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (healable_target(true, true))
|
||||
break;
|
||||
|
||||
sort_type = 106;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_XHEALFREQ(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (healable_target(true))
|
||||
break;
|
||||
|
||||
sort_type = 107;
|
||||
m_target_pool.sort([](Mob* l, Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_XHEALCNT(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (healable_target(true))
|
||||
break;
|
||||
|
||||
sort_type = 108;
|
||||
m_target_pool.sort([](const Mob* l, const Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && GT_ATWOUND(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_ATWOUND(l, r) && LT_ARMTYPE(l, r))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && EQ_ATWOUND(l, r) && EQ_ARMTYPE(l, r) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
if (healable_target())
|
||||
break;
|
||||
|
||||
sort_type = 109; // default
|
||||
m_target_pool.sort([](const Mob* l, const Mob* r) {
|
||||
if (GT_ALIVE(l, r))
|
||||
return true;
|
||||
uint32 current_time = Timer::GetCurrentTime();
|
||||
if (EQ_ALIVE(l, r) && GT_READY(l, r, current_time))
|
||||
return true;
|
||||
if (EQ_ALIVE(l, r) && EQ_READY(l, r, current_time) && LT_HPRATIO(l, r))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
m_active_heal_target = healable_target(false);
|
||||
if (!m_active_heal_target)
|
||||
m_active_heal_target = healable_target();
|
||||
|
||||
m_casting_target_poke = true;
|
||||
|
||||
#if (EQDEBUG >= 12)
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::bias_targets() - *** Post-processing state ***");
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation Settings:");
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_interval_ms = %u", m_interval_ms);
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_next_cast_time_ms = %u (current_time: %u, time_diff: %i)", m_next_cast_time_ms, Timer::GetCurrentTime(), ((int32)Timer::GetCurrentTime() - (int32)m_next_cast_time_ms));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_next_poke_time_ms = %u (current_time: %u, time_diff: %i)", m_next_poke_time_ms, Timer::GetCurrentTime(), ((int32)Timer::GetCurrentTime() - (int32)m_next_poke_time_ms));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_fast_heals = %s", ((m_fast_heals) ? ("true") : ("false")));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_adaptive_targeting = %s", ((m_adaptive_targeting) ? ("true") : ("false")));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_casting_override = %s", ((m_casting_override) ? ("true") : ("false")));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_casting_target_poke = %s", ((m_casting_target_poke) ? ("true") : ("false")));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_active_heal_target = %s", ((m_active_heal_target) ? ("true") : ("false")));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_is_active = %s", ((m_is_active) ? ("true") : ("false")));
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_member_list.size() = %i", m_member_pool.size());
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_cycle_list.size() = %i", m_cycle_pool.size());
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation::m_target_list.size() = %i", m_target_pool.size());
|
||||
if (m_member_pool.size()) { Log.Out(Logs::General, Logs::Error, "(std::shared_ptr<HealRotation>::use_count() = %i", m_member_pool.front()->MemberOfHealRotation()->use_count()); }
|
||||
else { Log.Out(Logs::General, Logs::Error, "(std::shared_ptr<HealRotation>::use_count() = unknown (0)"); }
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation Members:");
|
||||
int member_index = 0;
|
||||
for (auto mlist_iter : m_member_pool) {
|
||||
if (!mlist_iter) { continue; }
|
||||
Log.Out(Logs::General, Logs::Error, "(%i) %s (hrcast: %c)", (++member_index), mlist_iter->GetCleanName(), ((mlist_iter->AmICastingForHealRotation())?('T'):('F')));
|
||||
}
|
||||
if (!member_index) { Log.Out(Logs::General, Logs::Error, "(0) None"); }
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation Cycle:");
|
||||
int cycle_index = 0;
|
||||
for (auto clist_iter : m_cycle_pool) {
|
||||
if (!clist_iter) { continue; }
|
||||
Log.Out(Logs::General, Logs::Error, "(%i) %s", (++cycle_index), clist_iter->GetCleanName());
|
||||
}
|
||||
if (!cycle_index) { Log.Out(Logs::General, Logs::Error, "(0) None"); }
|
||||
Log.Out(Logs::General, Logs::Error, "HealRotation Targets: (sort type: %u)", sort_type);
|
||||
int target_index = 0;
|
||||
|
||||
for (auto tlist_iter : m_target_pool) {
|
||||
if (!tlist_iter) { continue; }
|
||||
Log.Out(Logs::General, Logs::Error, "(%i) %s (hp: %3.1f%%, at: %u, dontheal: %c, crit(base): %c(%c), safe(base): %c(%c), hcnt(ext): %u(%u), hfreq(ext): %f(%f))",
|
||||
(++target_index), tlist_iter->GetCleanName(),
|
||||
tlist_iter->GetHPRatio(),
|
||||
ClassArmorType(tlist_iter->GetClass()),
|
||||
((tlist_iter->DontHealMeBefore() > Timer::GetCurrentTime()) ? ('T') : ('F')),
|
||||
((tlist_iter->GetHPRatio()>m_critical_hp_ratio[ClassArmorType(tlist_iter->GetClass())]) ? ('F') : ('T')),
|
||||
((tlist_iter->GetHPRatio()>m_critical_hp_ratio[ARMOR_TYPE_UNKNOWN]) ? ('F') : ('T')),
|
||||
((tlist_iter->GetHPRatio()>m_safe_hp_ratio[ClassArmorType(tlist_iter->GetClass())]) ? ('T') : ('F')),
|
||||
((tlist_iter->GetHPRatio()>m_safe_hp_ratio[ARMOR_TYPE_UNKNOWN]) ? ('T') : ('F')),
|
||||
tlist_iter->HealRotationHealCount(),
|
||||
tlist_iter->HealRotationExtendedHealCount(),
|
||||
tlist_iter->HealRotationHealFrequency(),
|
||||
tlist_iter->HealRotationExtendedHealFrequency());
|
||||
}
|
||||
if (!target_index) { Log.Out(Logs::General, Logs::Error, "(0) None (hp: 0.0\%, at: 0, dontheal: F, crit(base): F(F), safe(base): F(F), hcnt(ext): 0(0), hfreq(ext): 0.0(0.0))"); }
|
||||
#endif
|
||||
}
|
||||
|
||||
void HealRotation::validate_hot()
|
||||
{
|
||||
if (!m_hot_target) {
|
||||
m_hot_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsTargetInPool(m_hot_target)) {
|
||||
m_hot_target = nullptr;
|
||||
m_hot_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHealRotationMemberClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case CLERIC:
|
||||
case DRUID:
|
||||
case SHAMAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHealRotationTargetMobType(Mob* target_mob)
|
||||
{
|
||||
if (!target_mob)
|
||||
return false;
|
||||
if (!target_mob->IsClient() && !target_mob->IsBot() && !target_mob->IsPet())
|
||||
return false;
|
||||
if (target_mob->IsPet() && (!target_mob->GetOwner() || (!target_mob->GetOwner()->IsClient() && !target_mob->GetOwner()->IsBot())))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // BOTS
|
||||
@@ -0,0 +1,165 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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 HEAL_ROTATION_H
|
||||
#define HEAL_ROTATION_H
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
#include "mob.h"
|
||||
|
||||
#define CASTING_CYCLE_MINIMUM_INTERVAL 1000
|
||||
#define CASTING_CYCLE_MINIMUM_INTERVAL_S 1
|
||||
#define CASTING_CYCLE_MAXIMUM_INTERVAL 30000
|
||||
#define CASTING_CYCLE_MAXIMUM_INTERVAL_S 30
|
||||
#define CASTING_CYCLE_DEFAULT_INTERVAL 5000
|
||||
#define CASTING_CYCLE_DEFAULT_INTERVAL_S 5
|
||||
#define POKE_PROPAGATION_DELAY 250
|
||||
#define ADVANCE_ROTATION_MINIMUM_INTERVAL 100
|
||||
#define HEALING_STATS_RESET_INTERVAL 60000
|
||||
#define HEALING_STATS_RESET_INTERVAL_S 60
|
||||
|
||||
#define SAFE_HP_RATIO_ABS 100.0f
|
||||
#define SAFE_HP_RATIO_BASE 95.0f
|
||||
|
||||
#define CRITICAL_HP_RATIO_ABS 0.0f
|
||||
#define CRITICAL_HP_RATIO_BASE 30.0f
|
||||
|
||||
struct HealingStats
|
||||
{
|
||||
uint32 last_heal_time_ms;
|
||||
uint32 heal_count;
|
||||
};
|
||||
|
||||
// Both members and targets use a shared_ptr to keep track of their HealRotation instance
|
||||
class HealRotation
|
||||
{
|
||||
public:
|
||||
HealRotation(Bot* hr_creator, uint32 interval_ms = CASTING_CYCLE_DEFAULT_INTERVAL, bool fast_heals = false, bool adaptive_targeting = false, bool casting_override = false);
|
||||
HealRotation(HealRotation* allocator_shunt) {}; // use should be limited to the shared_ptr<HealRotation> memory allocation call
|
||||
|
||||
void SetIntervalMS(uint32 interval_ms);
|
||||
void SetIntervalS(uint32 interval_s);
|
||||
void SetFastHeals(bool flag) { m_fast_heals = flag; }
|
||||
void SetAdaptiveTargeting(bool flag) { m_adaptive_targeting = flag; }
|
||||
void SetCastingOverride(bool flag) { m_casting_override = flag; }
|
||||
bool AddMemberToPool(Bot* hr_member);
|
||||
bool AddTargetToPool(Mob* hr_target);
|
||||
|
||||
uint32 CreationTimeMS() { return m_creation_time_ms; }
|
||||
uint32 LastHealTimeMS() { return m_last_heal_time_ms; }
|
||||
uint32 IntervalMS() { return m_interval_ms; }
|
||||
uint32 IntervalS() { return (m_interval_ms / 1000); }
|
||||
bool FastHeals() { return m_fast_heals; }
|
||||
bool AdaptiveTargeting() { return m_adaptive_targeting; }
|
||||
bool CastingOverride() { return m_casting_override; }
|
||||
bool RemoveMemberFromPool(Bot* hr_member);
|
||||
bool RemoveTargetFromPool(Mob* hr_target);
|
||||
|
||||
bool ClearMemberPool();
|
||||
bool ClearTargetPool();
|
||||
|
||||
Mob* HOTTarget() { return m_hot_target; }
|
||||
bool SetHOTTarget(Mob* hot_target);
|
||||
bool ClearHOTTarget();
|
||||
|
||||
bool Start();
|
||||
bool Stop();
|
||||
|
||||
bool IsActive() { return m_is_active; }
|
||||
bool IsHOTActive() { return m_hot_active; }
|
||||
bool CastingReady() { return (Timer::GetCurrentTime() >= m_next_cast_time_ms); }
|
||||
Bot* CastingMember();
|
||||
bool PokeCastingTarget();
|
||||
Mob* CastingTarget();
|
||||
bool AdvanceRotation(bool use_interval = true);
|
||||
|
||||
std::list<Bot*>* MemberList() { return &m_member_pool; }
|
||||
std::list<Bot*>* CycleList() { return &m_cycle_pool; }
|
||||
std::list<Mob*>* TargetList() { return &m_target_pool; }
|
||||
|
||||
bool IsMemberInPool(Bot* hr_member);
|
||||
bool IsTargetInPool(Mob* hr_target);
|
||||
bool IsHOTTarget(Mob* hot_target);
|
||||
|
||||
void SetMemberIsCasting(Bot* hr_member, bool flag = true);
|
||||
bool MemberIsCasting(Bot* hr_member);
|
||||
|
||||
void UpdateTargetHealingStats(Mob* hr_target);
|
||||
void StartNewTargetHealingStatsCycle(uint32 current_time);
|
||||
uint32 HealCount(Mob* hr_target);
|
||||
uint32 ExtendedHealCount(Mob* hr_target);
|
||||
float HealFrequency(Mob* hr_target);
|
||||
float ExtendedHealFrequency(Mob* hr_target);
|
||||
HealingStats* TargetHealingStats1(Mob* hr_target);
|
||||
HealingStats* TargetHealingStats2(Mob* hr_target);
|
||||
|
||||
bool SetArmorTypeSafeHPRatio(uint8 armor_type, float hp_ratio);
|
||||
bool SetArmorTypeCriticalHPRatio(uint8 armor_type, float hp_ratio);
|
||||
|
||||
float ArmorTypeSafeHPRatio(uint8 armor_type);
|
||||
float ArmorTypeCriticalHPRatio(uint8 armor_type);
|
||||
|
||||
void ResetArmorTypeHPLimits();
|
||||
|
||||
private:
|
||||
bool valid_state();
|
||||
void cycle_refresh();
|
||||
bool healable_target(bool use_class_at = true, bool critical_only = false);
|
||||
void bias_targets();
|
||||
void validate_hot();
|
||||
|
||||
uint32 m_creation_time_ms;
|
||||
uint32 m_last_heal_time_ms;
|
||||
uint32 m_interval_ms;
|
||||
uint32 m_next_cast_time_ms;
|
||||
uint32 m_next_poke_time_ms;
|
||||
uint32 m_healing_stats_begin_ms;
|
||||
bool m_fast_heals;
|
||||
bool m_adaptive_targeting;
|
||||
bool m_casting_override;
|
||||
bool m_casting_target_poke;
|
||||
bool m_active_heal_target;
|
||||
|
||||
bool m_is_active;
|
||||
|
||||
bool m_consumed;
|
||||
|
||||
Mob* m_hot_target;
|
||||
bool m_hot_active;
|
||||
|
||||
std::list<Bot*> m_member_pool;
|
||||
std::list<Bot*> m_cycle_pool;
|
||||
std::list<Mob*> m_target_pool;
|
||||
|
||||
std::map<Bot*, bool> m_member_is_casting;
|
||||
|
||||
std::map<Mob*, HealingStats> m_target_healing_stats_1;
|
||||
std::map<Mob*, HealingStats> m_target_healing_stats_2;
|
||||
|
||||
float m_safe_hp_ratio[ARMOR_TYPE_COUNT];
|
||||
float m_critical_hp_ratio[ARMOR_TYPE_COUNT];
|
||||
};
|
||||
|
||||
bool IsHealRotationMemberClass(uint8 class_id);
|
||||
bool IsHealRotationTargetMobType(Mob* target_mob);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOTS
|
||||
+27
-27
@@ -83,35 +83,35 @@ const NPCType *Horse::BuildHorseType(uint16 spell_id) {
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
NPCType* npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
strcpy(npc_type->name,"Unclaimed_Mount"); //this should never get used
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
strcpy(npc_type->name, "Unclaimed_Mount"); // this should never get used
|
||||
|
||||
strcpy(npc_type->special_abilities, "19,1^20,1^24,1");
|
||||
npc_type->cur_hp = 1;
|
||||
npc_type->max_hp = 1;
|
||||
npc_type->race = atoi(row[0]);
|
||||
npc_type->gender = atoi(row[1]); // Drogmor's are female horses. Yuck.
|
||||
npc_type->class_ = 1;
|
||||
npc_type->deity= 1;
|
||||
npc_type->level = 1;
|
||||
npc_type->npc_id = 0;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = atoi(row[2]); // mount color
|
||||
npc_type->helmtexture = atoi(row[2]); // mount color
|
||||
npc_type->runspeed = atof(row[3]);
|
||||
strcpy(npc_type->special_abilities, "19,1^20,1^24,1");
|
||||
npc_type->cur_hp = 1;
|
||||
npc_type->max_hp = 1;
|
||||
npc_type->race = atoi(row[0]);
|
||||
npc_type->gender = atoi(row[1]); // Drogmor's are female horses. Yuck.
|
||||
npc_type->class_ = 1;
|
||||
npc_type->deity = 1;
|
||||
npc_type->level = 1;
|
||||
npc_type->npc_id = 0;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = atoi(row[2]); // mount color
|
||||
npc_type->helmtexture = atoi(row[2]); // mount color
|
||||
npc_type->runspeed = atof(row[3]);
|
||||
|
||||
npc_type->light = 0;
|
||||
npc_type->STR = 75;
|
||||
npc_type->STA = 75;
|
||||
npc_type->DEX = 75;
|
||||
npc_type->AGI = 75;
|
||||
npc_type->INT = 75;
|
||||
npc_type->WIS = 75;
|
||||
npc_type->CHA = 75;
|
||||
horses_auto_delete.Insert(npc_type);
|
||||
npc_type->light = 0;
|
||||
npc_type->STR = 75;
|
||||
npc_type->STA = 75;
|
||||
npc_type->DEX = 75;
|
||||
npc_type->AGI = 75;
|
||||
npc_type->INT = 75;
|
||||
npc_type->WIS = 75;
|
||||
npc_type->CHA = 75;
|
||||
horses_auto_delete.Insert(npc_type);
|
||||
|
||||
return npc_type;
|
||||
return npc_type;
|
||||
}
|
||||
|
||||
void Client::SummonHorse(uint16 spell_id) {
|
||||
@@ -126,7 +126,7 @@ void Client::SummonHorse(uint16 spell_id) {
|
||||
|
||||
// No Horse, lets get them one.
|
||||
|
||||
Horse* horse = new Horse(this, spell_id, GetPosition());
|
||||
auto horse = new Horse(this, spell_id, GetPosition());
|
||||
|
||||
//we want to manage the spawn packet ourself.
|
||||
//another reason is we dont want quests executing on it.
|
||||
|
||||
+486
-304
File diff suppressed because it is too large
Load Diff
+73
-38
@@ -58,7 +58,7 @@ void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* ite
|
||||
if(max_cash > 0 && lts->avgcoin > 0 && EQEmu::ValueWithin(lts->avgcoin, min_cash, max_cash)) {
|
||||
float upper_chance = (float)(lts->avgcoin - min_cash) / (float)(max_cash - min_cash);
|
||||
float avg_cash_roll = (float)zone->random.Real(0.0, 1.0);
|
||||
|
||||
|
||||
if(avg_cash_roll < upper_chance) {
|
||||
cash = zone->random.Int(lts->avgcoin, max_cash);
|
||||
} else {
|
||||
@@ -119,8 +119,8 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
int charges = lds->Entries[i].multiplier;
|
||||
for(int j = 0; j < charges; ++j) {
|
||||
if(zone->random.Real(0.0, 100.0) <= lds->Entries[i].chance) {
|
||||
const Item_Struct* dbitem = GetItem(lds->Entries[i].item_id);
|
||||
npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel,
|
||||
const EQEmu::ItemBase* dbitem = GetItem(lds->Entries[i].item_id);
|
||||
npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel,
|
||||
lds->Entries[i].maxlevel, lds->Entries[i].equip_item > 0 ? true : false, false);
|
||||
}
|
||||
}
|
||||
@@ -137,27 +137,57 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
}
|
||||
|
||||
float roll_t = 0.0f;
|
||||
float roll_t_min = 0.0f;
|
||||
bool active_item_list = false;
|
||||
for(uint32 i = 0; i < lds->NumEntries; ++i) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[i].item_id);
|
||||
const EQEmu::ItemBase* db_item = GetItem(lds->Entries[i].item_id);
|
||||
if(db_item) {
|
||||
roll_t += lds->Entries[i].chance;
|
||||
active_item_list = true;
|
||||
}
|
||||
}
|
||||
|
||||
roll_t_min = roll_t;
|
||||
roll_t = EQEmu::ClampLower(roll_t, 100.0f);
|
||||
|
||||
if(!active_item_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
mindrop = EQEmu::ClampLower(mindrop, (uint8)1);
|
||||
int item_count = zone->random.Int(mindrop, droplimit);
|
||||
for(int i = 0; i < item_count; ++i) {
|
||||
for(int i = 0; i < mindrop; ++i) {
|
||||
float roll = (float)zone->random.Real(0.0, roll_t_min);
|
||||
for(uint32 j = 0; j < lds->NumEntries; ++j) {
|
||||
const EQEmu::ItemBase* db_item = GetItem(lds->Entries[j].item_id);
|
||||
if(db_item) {
|
||||
if(roll < lds->Entries[j].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
lds->Entries[j].maxlevel, lds->Entries[j].equip_item > 0 ? true : false, false);
|
||||
|
||||
int charges = (int)lds->Entries[i].multiplier;
|
||||
charges = EQEmu::ClampLower(charges, 1);
|
||||
|
||||
for(int k = 1; k < charges; ++k) {
|
||||
float c_roll = (float)zone->random.Real(0.0, 100.0);
|
||||
if(c_roll <= lds->Entries[i].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
lds->Entries[j].maxlevel, lds->Entries[j].equip_item > 0 ? true : false, false);
|
||||
}
|
||||
}
|
||||
|
||||
j = lds->NumEntries;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
roll -= lds->Entries[j].chance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = mindrop; i < droplimit; ++i) {
|
||||
float roll = (float)zone->random.Real(0.0, roll_t);
|
||||
for(uint32 j = 0; j < lds->NumEntries; ++j) {
|
||||
const Item_Struct* db_item = GetItem(lds->Entries[j].item_id);
|
||||
const EQEmu::ItemBase* db_item = GetItem(lds->Entries[j].item_id);
|
||||
if(db_item) {
|
||||
if(roll < lds->Entries[j].chance) {
|
||||
npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel,
|
||||
@@ -191,7 +221,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
|
||||
}
|
||||
|
||||
//if itemlist is null, just send wear changes
|
||||
void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) {
|
||||
void NPC::AddLootDrop(const EQEmu::ItemBase *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) {
|
||||
if(item2 == nullptr)
|
||||
return;
|
||||
|
||||
@@ -199,7 +229,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
if(!itemlist && !wearchange)
|
||||
return;
|
||||
|
||||
ServerLootItem_Struct* item = new ServerLootItem_Struct;
|
||||
auto item = new ServerLootItem_Struct;
|
||||
#if EQDEBUG>=11
|
||||
Log.Out(Logs::General, Logs::None, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
|
||||
#endif
|
||||
@@ -228,7 +258,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
if (equipit) {
|
||||
uint8 eslot = 0xFF;
|
||||
char newid[20];
|
||||
const Item_Struct* compitem = nullptr;
|
||||
const EQEmu::ItemBase* compitem = nullptr;
|
||||
bool found = false; // track if we found an empty slot we fit into
|
||||
int32 foundslot = -1; // for multi-slot items
|
||||
|
||||
@@ -242,7 +272,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
// it is an improvement.
|
||||
|
||||
if (!item2->NoPet) {
|
||||
for (int i = 0; !found && i<EmuConstants::EQUIPMENT_SIZE; i++) {
|
||||
for (int i = 0; !found && i < EQEmu::legacy::EQUIPMENT_SIZE; i++) {
|
||||
uint32 slots = (1 << i);
|
||||
if (item2->Slots & slots) {
|
||||
if(equipment[i])
|
||||
@@ -283,7 +313,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
// @merth: IDFile size has been increased, this needs to change
|
||||
uint16 emat;
|
||||
if(item2->Material <= 0
|
||||
|| item2->Slots & (1 << MainPrimary | 1 << MainSecondary)) {
|
||||
|| item2->Slots & (1 << EQEmu::legacy::SlotPrimary | 1 << EQEmu::legacy::SlotSecondary)) {
|
||||
memset(newid, 0, sizeof(newid));
|
||||
for(int i=0;i<7;i++){
|
||||
if (!isalpha(item2->IDFile[i])){
|
||||
@@ -297,42 +327,47 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
emat = item2->Material;
|
||||
}
|
||||
|
||||
if (foundslot == MainPrimary) {
|
||||
if (foundslot == EQEmu::legacy::SlotPrimary) {
|
||||
if (item2->Proc.Effect != 0)
|
||||
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
||||
|
||||
eslot = MaterialPrimary;
|
||||
eslot = EQEmu::textures::TexturePrimary;
|
||||
if (item2->Damage > 0)
|
||||
SendAddPlayerState(PlayerState::PrimaryWeaponEquipped);
|
||||
if (item2->IsType2HWeapon())
|
||||
SetTwoHanderEquipped(true);
|
||||
}
|
||||
else if (foundslot == MainSecondary
|
||||
&& (GetOwner() != nullptr || (GetLevel() >= 13 && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
||||
(item2->ItemType == ItemType1HSlash || item2->ItemType == ItemType1HBlunt || item2->ItemType == ItemTypeShield ||
|
||||
item2->ItemType == ItemType1HPiercing))
|
||||
else if (foundslot == EQEmu::legacy::SlotSecondary
|
||||
&& (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
|
||||
(item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield))
|
||||
{
|
||||
if (item2->Proc.Effect!=0)
|
||||
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
|
||||
|
||||
eslot = MaterialSecondary;
|
||||
eslot = EQEmu::textures::TextureSecondary;
|
||||
if (item2->Damage > 0)
|
||||
SendAddPlayerState(PlayerState::SecondaryWeaponEquipped);
|
||||
}
|
||||
else if (foundslot == MainHead) {
|
||||
eslot = MaterialHead;
|
||||
else if (foundslot == EQEmu::legacy::SlotHead) {
|
||||
eslot = EQEmu::textures::TextureHead;
|
||||
}
|
||||
else if (foundslot == MainChest) {
|
||||
eslot = MaterialChest;
|
||||
else if (foundslot == EQEmu::legacy::SlotChest) {
|
||||
eslot = EQEmu::textures::TextureChest;
|
||||
}
|
||||
else if (foundslot == MainArms) {
|
||||
eslot = MaterialArms;
|
||||
else if (foundslot == EQEmu::legacy::SlotArms) {
|
||||
eslot = EQEmu::textures::TextureArms;
|
||||
}
|
||||
else if (foundslot == MainWrist1 || foundslot == MainWrist2) {
|
||||
eslot = MaterialWrist;
|
||||
else if (foundslot == EQEmu::legacy::SlotWrist1 || foundslot == EQEmu::legacy::SlotWrist2) {
|
||||
eslot = EQEmu::textures::TextureWrist;
|
||||
}
|
||||
else if (foundslot == MainHands) {
|
||||
eslot = MaterialHands;
|
||||
else if (foundslot == EQEmu::legacy::SlotHands) {
|
||||
eslot = EQEmu::textures::TextureHands;
|
||||
}
|
||||
else if (foundslot == MainLegs) {
|
||||
eslot = MaterialLegs;
|
||||
else if (foundslot == EQEmu::legacy::SlotLegs) {
|
||||
eslot = EQEmu::textures::TextureLegs;
|
||||
}
|
||||
else if (foundslot == MainFeet) {
|
||||
eslot = MaterialFeet;
|
||||
else if (foundslot == EQEmu::legacy::SlotFeet) {
|
||||
eslot = EQEmu::textures::TextureFeet;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -380,17 +415,17 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
|
||||
SendAppearancePacket(AT_Light, GetActiveLightType());
|
||||
}
|
||||
|
||||
void NPC::AddItem(const Item_Struct* item, uint16 charges, bool equipitem) {
|
||||
void NPC::AddItem(const EQEmu::ItemBase* item, uint16 charges, bool equipitem) {
|
||||
//slot isnt needed, its determined from the item.
|
||||
AddLootDrop(item, &itemlist, charges, 1, 127, equipitem, equipitem);
|
||||
AddLootDrop(item, &itemlist, charges, 1, 255, equipitem, equipitem);
|
||||
}
|
||||
|
||||
void NPC::AddItem(uint32 itemid, uint16 charges, bool equipitem) {
|
||||
//slot isnt needed, its determined from the item.
|
||||
const Item_Struct * i = database.GetItem(itemid);
|
||||
const EQEmu::ItemBase * i = database.GetItem(itemid);
|
||||
if(i == nullptr)
|
||||
return;
|
||||
AddLootDrop(i, &itemlist, charges, 1, 127, equipitem, equipitem);
|
||||
AddLootDrop(i, &itemlist, charges, 1, 255, equipitem, equipitem);
|
||||
}
|
||||
|
||||
void NPC::AddLootTable() {
|
||||
|
||||
+119
-17
@@ -232,27 +232,27 @@ void Lua_Client::SetBindPoint() {
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone);
|
||||
self->SetBindPoint(0, to_zone);
|
||||
}
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance);
|
||||
self->SetBindPoint(0, to_zone, to_instance);
|
||||
}
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x,0.0f,0.0f));
|
||||
self->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x,0.0f,0.0f));
|
||||
}
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, 0.0f));
|
||||
self->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, 0.0f));
|
||||
}
|
||||
|
||||
void Lua_Client::SetBindPoint(int to_zone, int to_instance, float new_x, float new_y, float new_z) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, new_z));
|
||||
self->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, new_z));
|
||||
}
|
||||
|
||||
float Lua_Client::GetBindX() {
|
||||
@@ -350,6 +350,11 @@ const char *Lua_Client::AccountName() {
|
||||
return self->AccountName();
|
||||
}
|
||||
|
||||
int Lua_Client::GetAccountAge() {
|
||||
Lua_Safe_Call_Int();
|
||||
return time(nullptr) - self->GetAccountCreation();
|
||||
}
|
||||
|
||||
int Lua_Client::Admin() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->Admin();
|
||||
@@ -427,27 +432,27 @@ void Lua_Client::IncreaseLanguageSkill(int skill_id, int value) {
|
||||
|
||||
int Lua_Client::GetRawSkill(int skill_id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetRawSkill(static_cast<SkillUseTypes>(skill_id));
|
||||
return self->GetRawSkill(static_cast<EQEmu::skills::SkillType>(skill_id));
|
||||
}
|
||||
|
||||
bool Lua_Client::HasSkill(int skill_id) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasSkill(static_cast<SkillUseTypes>(skill_id));
|
||||
return self->HasSkill(static_cast<EQEmu::skills::SkillType>(skill_id));
|
||||
}
|
||||
|
||||
bool Lua_Client::CanHaveSkill(int skill_id) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CanHaveSkill(static_cast<SkillUseTypes>(skill_id));
|
||||
return self->CanHaveSkill(static_cast<EQEmu::skills::SkillType>(skill_id));
|
||||
}
|
||||
|
||||
void Lua_Client::SetSkill(int skill_id, int value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetSkill(static_cast<SkillUseTypes>(skill_id), value);
|
||||
self->SetSkill(static_cast<EQEmu::skills::SkillType>(skill_id), value);
|
||||
}
|
||||
|
||||
void Lua_Client::AddSkill(int skill_id, int value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AddSkill(static_cast<SkillUseTypes>(skill_id), value);
|
||||
self->AddSkill(static_cast<EQEmu::skills::SkillType>(skill_id), value);
|
||||
}
|
||||
|
||||
void Lua_Client::CheckSpecializeIncrease(int spell_id) {
|
||||
@@ -457,12 +462,12 @@ void Lua_Client::CheckSpecializeIncrease(int spell_id) {
|
||||
|
||||
void Lua_Client::CheckIncreaseSkill(int skill_id, Lua_Mob target) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->CheckIncreaseSkill(static_cast<SkillUseTypes>(skill_id), target);
|
||||
self->CheckIncreaseSkill(static_cast<EQEmu::skills::SkillType>(skill_id), target);
|
||||
}
|
||||
|
||||
void Lua_Client::CheckIncreaseSkill(int skill_id, Lua_Mob target, int chance_mod) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->CheckIncreaseSkill(static_cast<SkillUseTypes>(skill_id), target, chance_mod);
|
||||
self->CheckIncreaseSkill(static_cast<EQEmu::skills::SkillType>(skill_id), target, chance_mod);
|
||||
}
|
||||
|
||||
void Lua_Client::SetLanguageSkill(int language, int value) {
|
||||
@@ -472,7 +477,7 @@ void Lua_Client::SetLanguageSkill(int language, int value) {
|
||||
|
||||
int Lua_Client::MaxSkill(int skill_id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->MaxSkill(static_cast<SkillUseTypes>(skill_id));
|
||||
return self->MaxSkill(static_cast<EQEmu::skills::SkillType>(skill_id));
|
||||
}
|
||||
|
||||
bool Lua_Client::IsMedding() {
|
||||
@@ -525,6 +530,11 @@ void Lua_Client::UnmemSpell(int slot, bool update_client) {
|
||||
self->UnmemSpell(slot, update_client);
|
||||
}
|
||||
|
||||
void Lua_Client::UnmemSpellBySpellID(int32 spell_id) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->UnmemSpellBySpellID(spell_id);
|
||||
}
|
||||
|
||||
void Lua_Client::UnmemSpellAll() {
|
||||
Lua_Safe_Call_Void();
|
||||
self->UnmemSpellAll();
|
||||
@@ -570,6 +580,16 @@ void Lua_Client::TrainDisc(int itemid) {
|
||||
self->TrainDiscipline(itemid);
|
||||
}
|
||||
|
||||
void Lua_Client::TrainDiscBySpellID(int32 spell_id) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->TrainDiscBySpellID(spell_id);
|
||||
}
|
||||
|
||||
int Lua_Client::GetDiscSlotBySpellID(int32 spell_id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetDiscSlotBySpellID(spell_id);
|
||||
}
|
||||
|
||||
void Lua_Client::UntrainDisc(int slot) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->UntrainDisc(slot);
|
||||
@@ -834,12 +854,12 @@ void Lua_Client::SetAATitle(const char *title) {
|
||||
|
||||
int Lua_Client::GetClientVersion() {
|
||||
Lua_Safe_Call_Int();
|
||||
return static_cast<unsigned int>(self->GetClientVersion());
|
||||
return static_cast<unsigned int>(self->ClientVersion());
|
||||
}
|
||||
|
||||
uint32 Lua_Client::GetClientVersionBit() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetClientVersionBit();
|
||||
return self->ClientVersionBit();
|
||||
}
|
||||
|
||||
void Lua_Client::SetTitleSuffix(const char *text) {
|
||||
@@ -1024,7 +1044,17 @@ void Lua_Client::AddLevelBasedExp(int exp_pct, int max_level) {
|
||||
|
||||
void Lua_Client::IncrementAA(int aa) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->IncrementAA(aa);
|
||||
self->IncrementAlternateAdvancementRank(aa);
|
||||
}
|
||||
|
||||
bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->GrantAlternateAdvancementAbility(aa_id, points);
|
||||
}
|
||||
|
||||
bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost);
|
||||
}
|
||||
|
||||
void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z) {
|
||||
@@ -1037,6 +1067,11 @@ void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, int co
|
||||
self->MarkSingleCompassLoc(in_x, in_y, in_z, count);
|
||||
}
|
||||
|
||||
void Lua_Client::ClearCompassMark() {
|
||||
Lua_Safe_Call_Void();
|
||||
self->MarkSingleCompassLoc(0,0,0,0);
|
||||
}
|
||||
|
||||
int Lua_Client::GetNextAvailableSpellBookSlot() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetNextAvailableSpellBookSlot();
|
||||
@@ -1062,6 +1097,11 @@ void Lua_Client::AssignTask(int task, int npc_id) {
|
||||
self->AssignTask(task, npc_id);
|
||||
}
|
||||
|
||||
void Lua_Client::AssignTask(int task, int npc_id, bool enforce_level_requirement) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->AssignTask(task, npc_id, enforce_level_requirement);
|
||||
}
|
||||
|
||||
void Lua_Client::FailTask(int task) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->FailTask(task);
|
||||
@@ -1255,6 +1295,51 @@ void Lua_Client::PlayMP3(std::string file)
|
||||
self->PlayMP3(file.c_str());
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper, silver);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper, silver, gold);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper, silver, gold, platinum);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper, silver, gold, platinum, itemid);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper, silver, gold, platinum, itemid, exp);
|
||||
}
|
||||
|
||||
void Lua_Client::QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp, bool faction) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(target, copper, silver, gold, platinum, itemid, exp, faction);
|
||||
}
|
||||
|
||||
uint32 Lua_Client::GetMoney(uint8 type, uint8 subtype) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMoney(type, subtype);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_client() {
|
||||
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
||||
.def(luabind::constructor<>())
|
||||
@@ -1325,6 +1410,7 @@ luabind::scope lua_register_client() {
|
||||
.def("GetRawItemAC", (int(Lua_Client::*)(void))&Lua_Client::GetRawItemAC)
|
||||
.def("AccountID", (uint32(Lua_Client::*)(void))&Lua_Client::AccountID)
|
||||
.def("AccountName", (const char *(Lua_Client::*)(void))&Lua_Client::AccountName)
|
||||
.def("GetAccountAge", (int(Lua_Client::*)(void))&Lua_Client::GetAccountAge)
|
||||
.def("Admin", (int(Lua_Client::*)(void))&Lua_Client::Admin)
|
||||
.def("CharacterID", (uint32(Lua_Client::*)(void))&Lua_Client::CharacterID)
|
||||
.def("GuildRank", (int(Lua_Client::*)(void))&Lua_Client::GuildRank)
|
||||
@@ -1360,6 +1446,7 @@ luabind::scope lua_register_client() {
|
||||
.def("MemSpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::MemSpell)
|
||||
.def("UnmemSpell", (void(Lua_Client::*)(int))&Lua_Client::UnmemSpell)
|
||||
.def("UnmemSpell", (void(Lua_Client::*)(int,bool))&Lua_Client::UnmemSpell)
|
||||
.def("UnmemSpellBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::UnmemSpellBySpellID)
|
||||
.def("UnmemSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnmemSpellAll)
|
||||
.def("UnmemSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnmemSpellAll)
|
||||
.def("ScribeSpell", (void(Lua_Client::*)(int,int))&Lua_Client::ScribeSpell)
|
||||
@@ -1369,6 +1456,8 @@ luabind::scope lua_register_client() {
|
||||
.def("UnscribeSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnscribeSpellAll)
|
||||
.def("UnscribeSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnscribeSpellAll)
|
||||
.def("TrainDisc", (void(Lua_Client::*)(int))&Lua_Client::TrainDisc)
|
||||
.def("TrainDiscBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::TrainDiscBySpellID)
|
||||
.def("GetDiscSlotBySpellID", (int(Lua_Client::*)(int32))&Lua_Client::GetDiscSlotBySpellID)
|
||||
.def("UntrainDisc", (void(Lua_Client::*)(int))&Lua_Client::UntrainDisc)
|
||||
.def("UntrainDisc", (void(Lua_Client::*)(int,bool))&Lua_Client::UntrainDisc)
|
||||
.def("UntrainDiscAll", (void(Lua_Client::*)(void))&Lua_Client::UntrainDiscAll)
|
||||
@@ -1460,13 +1549,17 @@ luabind::scope lua_register_client() {
|
||||
.def("AddLevelBasedExp", (void(Lua_Client::*)(int))&Lua_Client::AddLevelBasedExp)
|
||||
.def("AddLevelBasedExp", (void(Lua_Client::*)(int,int))&Lua_Client::AddLevelBasedExp)
|
||||
.def("IncrementAA", (void(Lua_Client::*)(int))&Lua_Client::IncrementAA)
|
||||
.def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int))&Lua_Client::GrantAlternateAdvancementAbility)
|
||||
.def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int, bool))&Lua_Client::GrantAlternateAdvancementAbility)
|
||||
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float))&Lua_Client::MarkSingleCompassLoc)
|
||||
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc)
|
||||
.def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark)
|
||||
.def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(void))&Lua_Client::GetNextAvailableSpellBookSlot)
|
||||
.def("GetNextAvailableSpellBookSlot", (int(Lua_Client::*)(int))&Lua_Client::GetNextAvailableSpellBookSlot)
|
||||
.def("FindSpellBookSlotBySpellID", (int(Lua_Client::*)(int))&Lua_Client::FindSpellBookSlotBySpellID)
|
||||
.def("UpdateTaskActivity", (void(Lua_Client::*)(int,int,int))&Lua_Client::UpdateTaskActivity)
|
||||
.def("AssignTask", (void(Lua_Client::*)(int,int))&Lua_Client::AssignTask)
|
||||
.def("AssignTask", (void(Lua_Client::*)(int,int,bool))&Lua_Client::AssignTask)
|
||||
.def("FailTask", (void(Lua_Client::*)(int))&Lua_Client::FailTask)
|
||||
.def("IsTaskCompleted", (bool(Lua_Client::*)(int))&Lua_Client::IsTaskCompleted)
|
||||
.def("IsTaskActive", (bool(Lua_Client::*)(int))&Lua_Client::IsTaskActive)
|
||||
@@ -1504,7 +1597,16 @@ luabind::scope lua_register_client() {
|
||||
.def("SetConsumption", (void(Lua_Client::*)(int, int))&Lua_Client::SetConsumption)
|
||||
.def("SendMarqueeMessage", (void(Lua_Client::*)(uint32, uint32, uint32, uint32, uint32, std::string))&Lua_Client::SendMarqueeMessage)
|
||||
.def("SendColoredText", (void(Lua_Client::*)(uint32, std::string))&Lua_Client::SendColoredText)
|
||||
.def("PlayMP3", (void(Lua_Client::*)(std::string))&Lua_Client::PlayMP3);
|
||||
.def("PlayMP3", (void(Lua_Client::*)(std::string))&Lua_Client::PlayMP3)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32, uint32))&Lua_Client::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Client::*)(Lua_Mob, uint32, uint32, uint32, uint32, uint32, uint32, bool))&Lua_Client::QuestReward)
|
||||
.def("GetMoney", (uint32(Lua_Client::*)(uint8, uint8))&Lua_Client::GetMoney);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_inventory_where() {
|
||||
|
||||
+19
-2
@@ -131,6 +131,7 @@ public:
|
||||
void MemSpell(int spell_id, int slot, bool update_client);
|
||||
void UnmemSpell(int slot);
|
||||
void UnmemSpell(int slot, bool update_client);
|
||||
void UnmemSpellBySpellID(int32 spell_id);
|
||||
void UnmemSpellAll();
|
||||
void UnmemSpellAll(bool update_client);
|
||||
void ScribeSpell(int spell_id, int slot);
|
||||
@@ -140,6 +141,8 @@ public:
|
||||
void UnscribeSpellAll();
|
||||
void UnscribeSpellAll(bool update_client);
|
||||
void TrainDisc(int itemid);
|
||||
void TrainDiscBySpellID(int32 spell_id);
|
||||
int GetDiscSlotBySpellID(int32 spell_id);
|
||||
void UntrainDisc(int slot);
|
||||
void UntrainDisc(int slot, bool update_client);
|
||||
void UntrainDiscAll();
|
||||
@@ -166,9 +169,9 @@ public:
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
bool attuned);
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
void SummonItem(uint32 item_id, int charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5,
|
||||
bool attuned, int to_slot);
|
||||
void SetStats(int type, int value);
|
||||
void IncStats(int type, int value);
|
||||
@@ -233,13 +236,17 @@ public:
|
||||
void AddLevelBasedExp(int exp_pct);
|
||||
void AddLevelBasedExp(int exp_pct, int max_level);
|
||||
void IncrementAA(int aa);
|
||||
bool GrantAlternateAdvancementAbility(int aa_id, int points);
|
||||
bool GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost);
|
||||
void MarkSingleCompassLoc(float in_x, float in_y, float in_z);
|
||||
void MarkSingleCompassLoc(float in_x, float in_y, float in_z, int count);
|
||||
void ClearCompassMark();
|
||||
int GetNextAvailableSpellBookSlot();
|
||||
int GetNextAvailableSpellBookSlot(int start);
|
||||
int FindSpellBookSlotBySpellID(int spell_id);
|
||||
void UpdateTaskActivity(int task, int activity, int count);
|
||||
void AssignTask(int task, int npc_id);
|
||||
void AssignTask(int task, int npc_id, bool enforce_level_requirement);
|
||||
void FailTask(int task);
|
||||
bool IsTaskCompleted(int task);
|
||||
bool IsTaskActive(int task);
|
||||
@@ -253,6 +260,7 @@ public:
|
||||
int GetAggroCount();
|
||||
uint64 GetCarriedMoney();
|
||||
uint64 GetAllMoney();
|
||||
uint32 GetMoney(uint8 type, uint8 subtype);
|
||||
void OpenLFGuildWindow();
|
||||
void Signal(uint32 id);
|
||||
void AddAlternateCurrencyValue(uint32 currency, int amount);
|
||||
@@ -260,6 +268,7 @@ public:
|
||||
bool HasSpellScribed(int spell_id);
|
||||
void SetAccountFlag(std::string flag, std::string val);
|
||||
std::string GetAccountFlag(std::string flag);
|
||||
int GetAccountAge();
|
||||
Lua_Group GetGroup();
|
||||
Lua_Raid GetRaid();
|
||||
bool PutItemInInventory(int slot_id, Lua_ItemInst inst);
|
||||
@@ -278,6 +287,14 @@ public:
|
||||
void SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string msg);
|
||||
void SendColoredText(uint32 type, std::string msg);
|
||||
void PlayMP3(std::string file);
|
||||
void QuestReward(Lua_Mob target);
|
||||
void QuestReward(Lua_Mob target, uint32 copper);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp);
|
||||
void QuestReward(Lua_Mob target, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, uint32 itemid, uint32 exp, bool faction);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifdef LUA_EQEMU
|
||||
|
||||
#include "lua.hpp"
|
||||
#include <luabind/luabind.hpp>
|
||||
#include "lua_encounter.h"
|
||||
#include "encounter.h"
|
||||
|
||||
|
||||
luabind::scope lua_register_encounter() {
|
||||
return luabind::class_<Lua_Encounter>("Encounter");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef EQEMU_LUA_ENCOUNTER_H
|
||||
#define EQEMU_LUA_ENCOUNTER_H
|
||||
#ifdef LUA_EQEMU
|
||||
|
||||
#include "lua_ptr.h"
|
||||
|
||||
class Encounter;
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
namespace adl {
|
||||
class object;
|
||||
}
|
||||
}
|
||||
|
||||
luabind::scope lua_register_encounter();
|
||||
|
||||
class Lua_Encounter : public Lua_Ptr<Encounter>
|
||||
{
|
||||
typedef Encounter NativeType;
|
||||
public:
|
||||
Lua_Encounter() { SetLuaPtrData(nullptr); }
|
||||
Lua_Encounter(Encounter *d) { SetLuaPtrData(reinterpret_cast<Encounter*>(d)); }
|
||||
virtual ~Lua_Encounter() { }
|
||||
|
||||
operator Encounter*() {
|
||||
return reinterpret_cast<Encounter*>(GetLuaPtrData());
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
+149
-92
@@ -18,6 +18,8 @@
|
||||
#include "qglobals.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "encounter.h"
|
||||
#include "lua_encounter.h"
|
||||
|
||||
struct Events { };
|
||||
struct Factions { };
|
||||
@@ -34,6 +36,8 @@ struct lua_registered_event {
|
||||
|
||||
extern std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
|
||||
extern std::map<std::string, bool> lua_encounters_loaded;
|
||||
extern std::map<std::string, Encounter *> lua_encounters;
|
||||
|
||||
extern void MapOpcodes();
|
||||
extern void ClearMappedOpcode(EmuOpcode op);
|
||||
|
||||
@@ -42,19 +46,23 @@ void unregister_event(std::string package_name, std::string name, int evt);
|
||||
void load_encounter(std::string name) {
|
||||
if(lua_encounters_loaded.count(name) > 0)
|
||||
return;
|
||||
|
||||
auto enc = new Encounter(name.c_str());
|
||||
entity_list.AddEncounter(enc);
|
||||
lua_encounters[name] = enc;
|
||||
lua_encounters_loaded[name] = true;
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, 0);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, "", 0);
|
||||
}
|
||||
|
||||
void load_encounter_with_data(std::string name, std::string info_str) {
|
||||
if(lua_encounters_loaded.count(name) > 0)
|
||||
return;
|
||||
|
||||
auto enc = new Encounter(name.c_str());
|
||||
entity_list.AddEncounter(enc);
|
||||
lua_encounters[name] = enc;
|
||||
lua_encounters_loaded[name] = true;
|
||||
std::vector<EQEmu::Any> info_ptrs;
|
||||
info_ptrs.push_back(&info_str);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, 0, &info_ptrs);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, "", 0, &info_ptrs);
|
||||
}
|
||||
|
||||
void unload_encounter(std::string name) {
|
||||
@@ -80,8 +88,10 @@ void unload_encounter(std::string name) {
|
||||
}
|
||||
}
|
||||
|
||||
lua_encounters[name]->Depop();
|
||||
lua_encounters.erase(name);
|
||||
lua_encounters_loaded.erase(name);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, 0);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, "", 0);
|
||||
}
|
||||
|
||||
void unload_encounter_with_data(std::string name, std::string info_str) {
|
||||
@@ -109,10 +119,12 @@ void unload_encounter_with_data(std::string name, std::string info_str) {
|
||||
}
|
||||
}
|
||||
|
||||
lua_encounters[name]->Depop();
|
||||
lua_encounters.erase(name);
|
||||
lua_encounters_loaded.erase(name);
|
||||
std::vector<EQEmu::Any> info_ptrs;
|
||||
info_ptrs.push_back(&info_str);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, 0, &info_ptrs);
|
||||
parse->EventEncounter(EVENT_ENCOUNTER_UNLOAD, name, "", 0, &info_ptrs);
|
||||
}
|
||||
|
||||
void register_event(std::string package_name, std::string name, int evt, luabind::adl::object func) {
|
||||
@@ -285,6 +297,10 @@ void lua_set_timer(const char *timer, int time_ms, Lua_Mob mob) {
|
||||
quest_manager.settimerMS(timer, time_ms, mob);
|
||||
}
|
||||
|
||||
void lua_set_timer(const char *timer, int time_ms, Lua_Encounter enc) {
|
||||
quest_manager.settimerMS(timer, time_ms, enc);
|
||||
}
|
||||
|
||||
void lua_stop_timer(const char *timer) {
|
||||
quest_manager.stoptimer(timer);
|
||||
}
|
||||
@@ -297,6 +313,10 @@ void lua_stop_timer(const char *timer, Lua_Mob mob) {
|
||||
quest_manager.stoptimer(timer, mob);
|
||||
}
|
||||
|
||||
void lua_stop_timer(const char *timer, Lua_Encounter enc) {
|
||||
quest_manager.stoptimer(timer, enc);
|
||||
}
|
||||
|
||||
void lua_stop_all_timers() {
|
||||
quest_manager.stopalltimers();
|
||||
}
|
||||
@@ -309,6 +329,10 @@ void lua_stop_all_timers(Lua_Mob mob) {
|
||||
quest_manager.stopalltimers(mob);
|
||||
}
|
||||
|
||||
void lua_stop_all_timers(Lua_Encounter enc) {
|
||||
quest_manager.stopalltimers(enc);
|
||||
}
|
||||
|
||||
void lua_depop() {
|
||||
quest_manager.depop(0);
|
||||
}
|
||||
@@ -386,7 +410,11 @@ void lua_create_guild(const char *name, const char *leader) {
|
||||
}
|
||||
|
||||
void lua_set_time(int hour, int min) {
|
||||
quest_manager.settime(hour, min);
|
||||
quest_manager.settime(hour, min, true);
|
||||
}
|
||||
|
||||
void lua_set_time(int hour, int min, bool update_world) {
|
||||
quest_manager.settime(hour, min, update_world);
|
||||
}
|
||||
|
||||
void lua_signal(int npc_id, int signal_id) {
|
||||
@@ -485,16 +513,16 @@ void lua_toggle_spawn_event(int event_id, bool enable, bool strict, bool reset)
|
||||
quest_manager.toggle_spawn_event(event_id, enable, strict, reset);
|
||||
}
|
||||
|
||||
void lua_summon_burried_player_corpse(uint32 char_id, float x, float y, float z, float h) {
|
||||
quest_manager.summonburriedplayercorpse(char_id, glm::vec4(x, y, z, h));
|
||||
void lua_summon_buried_player_corpse(uint32 char_id, float x, float y, float z, float h) {
|
||||
quest_manager.summonburiedplayercorpse(char_id, glm::vec4(x, y, z, h));
|
||||
}
|
||||
|
||||
void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, float h) {
|
||||
quest_manager.summonallplayercorpses(char_id, glm::vec4(x, y, z, h));
|
||||
}
|
||||
|
||||
int lua_get_player_burried_corpse_count(uint32 char_id) {
|
||||
return quest_manager.getplayerburriedcorpsecount(char_id);
|
||||
int lua_get_player_buried_corpse_count(uint32 char_id) {
|
||||
return quest_manager.getplayerburiedcorpsecount(char_id);
|
||||
}
|
||||
|
||||
bool lua_bury_player_corpse(uint32 char_id) {
|
||||
@@ -776,6 +804,18 @@ void lua_destroy_instance(uint32 instance_id) {
|
||||
quest_manager.DestroyInstance(instance_id);
|
||||
}
|
||||
|
||||
void lua_update_instance_timer(uint16 instance_id, uint32 new_duration) {
|
||||
quest_manager.UpdateInstanceTimer(instance_id, new_duration);
|
||||
}
|
||||
|
||||
uint32 lua_get_instance_timer() {
|
||||
return quest_manager.GetInstanceTimer();
|
||||
}
|
||||
|
||||
uint32 lua_get_instance_timer_by_id(uint16 instance_id) {
|
||||
return quest_manager.GetInstanceTimerByID(instance_id);
|
||||
}
|
||||
|
||||
int lua_get_instance_id(const char *zone, uint32 version) {
|
||||
return quest_manager.GetInstanceID(zone, version);
|
||||
}
|
||||
@@ -979,7 +1019,7 @@ int lua_get_zone_weather() {
|
||||
|
||||
luabind::adl::object lua_get_zone_time(lua_State *L) {
|
||||
TimeOfDay_Struct eqTime;
|
||||
zone->zone_time.getEQTimeOfDay(time(0), &eqTime);
|
||||
zone->zone_time.GetCurrentEQTimeOfDay(time(0), &eqTime);
|
||||
|
||||
luabind::adl::object ret = luabind::newtable(L);
|
||||
ret["zone_hour"] = eqTime.hour - 1;
|
||||
@@ -1176,8 +1216,8 @@ void lua_add_spawn_point(luabind::adl::object table) {
|
||||
|
||||
lua_remove_spawn_point(spawn2_id);
|
||||
|
||||
Spawn2 *t = new Spawn2(spawn2_id, spawngroup_id, x, y, z, heading, respawn, variance, timeleft, grid, condition_id,
|
||||
condition_min_value, enabled, static_cast<EmuAppearance>(animation));
|
||||
auto t = new Spawn2(spawn2_id, spawngroup_id, x, y, z, heading, respawn, variance, timeleft, grid,
|
||||
condition_id, condition_min_value, enabled, static_cast<EmuAppearance>(animation));
|
||||
zone->spawn2_list.Insert(t);
|
||||
}
|
||||
}
|
||||
@@ -1242,6 +1282,10 @@ void lua_clear_npctype_cache(int npctype_id) {
|
||||
quest_manager.ClearNPCTypeCache(npctype_id);
|
||||
}
|
||||
|
||||
void lua_reloadzonestaticdata() {
|
||||
quest_manager.ReloadZoneStaticData();
|
||||
}
|
||||
|
||||
double lua_clock() {
|
||||
timeval read_time;
|
||||
gettimeofday(&read_time, nullptr);
|
||||
@@ -1260,6 +1304,10 @@ void lua_debug(std::string message, int level) {
|
||||
Log.Out(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
|
||||
}
|
||||
|
||||
void lua_update_zone_header(std::string type, std::string value) {
|
||||
quest_manager.UpdateZoneHeader(type, value);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@@ -1296,7 +1344,7 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
return;
|
||||
}
|
||||
|
||||
NPCType* npc_type = new NPCType;
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
|
||||
|
||||
@@ -1352,15 +1400,15 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
|
||||
LuaCreateNPCParse(drakkin_heritage, uint32, 0);
|
||||
LuaCreateNPCParse(drakkin_tattoo, uint32, 0);
|
||||
LuaCreateNPCParse(drakkin_details, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[0], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[1], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[2], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[3], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[4], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[5], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[6], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[7], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint[8], uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Head.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Chest.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Arms.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Wrist.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Hands.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Legs.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Feet.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Primary.Color, uint32, 0);
|
||||
LuaCreateNPCParse(armor_tint.Secondary.Color, uint32, 0);
|
||||
LuaCreateNPCParse(min_dmg, uint32, 2);
|
||||
LuaCreateNPCParse(max_dmg, uint32, 4);
|
||||
LuaCreateNPCParse(attack_count, int16, 0);
|
||||
@@ -1438,12 +1486,15 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("set_timer", (void(*)(const char*, int))&lua_set_timer),
|
||||
luabind::def("set_timer", (void(*)(const char*, int, Lua_ItemInst))&lua_set_timer),
|
||||
luabind::def("set_timer", (void(*)(const char*, int, Lua_Mob))&lua_set_timer),
|
||||
luabind::def("set_timer", (void(*)(const char*, int, Lua_Encounter))&lua_set_timer),
|
||||
luabind::def("stop_timer", (void(*)(const char*))&lua_stop_timer),
|
||||
luabind::def("stop_timer", (void(*)(const char*, Lua_ItemInst))&lua_stop_timer),
|
||||
luabind::def("stop_timer", (void(*)(const char*, Lua_Mob))&lua_stop_timer),
|
||||
luabind::def("stop_timer", (void(*)(const char*, Lua_Encounter))&lua_stop_timer),
|
||||
luabind::def("stop_all_timers", (void(*)(void))&lua_stop_all_timers),
|
||||
luabind::def("stop_all_timers", (void(*)(Lua_ItemInst))&lua_stop_all_timers),
|
||||
luabind::def("stop_all_timers", (void(*)(Lua_Mob))&lua_stop_all_timers),
|
||||
luabind::def("stop_all_timers", (void(*)(Lua_Encounter))&lua_stop_all_timers),
|
||||
luabind::def("depop", (void(*)(void))&lua_depop),
|
||||
luabind::def("depop", (void(*)(int))&lua_depop),
|
||||
luabind::def("depop_with_timer", (void(*)(void))&lua_depop_with_timer),
|
||||
@@ -1463,7 +1514,8 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("set_sky", &lua_set_sky),
|
||||
luabind::def("set_guild", &lua_set_guild),
|
||||
luabind::def("create_guild", &lua_create_guild),
|
||||
luabind::def("set_time", &lua_set_time),
|
||||
luabind::def("set_time", (void(*)(int, int))&lua_set_time),
|
||||
luabind::def("set_time", (void(*)(int, int, bool))&lua_set_time),
|
||||
luabind::def("signal", (void(*)(int,int))&lua_signal),
|
||||
luabind::def("signal", (void(*)(int,int,int))&lua_signal),
|
||||
luabind::def("set_global", &lua_set_global),
|
||||
@@ -1488,9 +1540,9 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("spawn_condition", &lua_spawn_condition),
|
||||
luabind::def("get_spawn_condition", &lua_get_spawn_condition),
|
||||
luabind::def("toggle_spawn_event", &lua_toggle_spawn_event),
|
||||
luabind::def("summon_burried_player_corpse", &lua_summon_burried_player_corpse),
|
||||
luabind::def("summon_buried_player_corpse", &lua_summon_buried_player_corpse),
|
||||
luabind::def("summon_all_player_corpses", &lua_summon_all_player_corpses),
|
||||
luabind::def("get_player_burried_corpse_count", &lua_get_player_burried_corpse_count),
|
||||
luabind::def("get_player_buried_corpse_count", &lua_get_player_buried_corpse_count),
|
||||
luabind::def("bury_player_corpse", &lua_bury_player_corpse),
|
||||
luabind::def("task_selector", &lua_task_selector),
|
||||
luabind::def("task_set_selector", &lua_task_set_selector),
|
||||
@@ -1540,6 +1592,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("get_guild_name_by_id", &lua_get_guild_name_by_id),
|
||||
luabind::def("create_instance", &lua_create_instance),
|
||||
luabind::def("destroy_instance", &lua_destroy_instance),
|
||||
luabind::def("update_instance_timer", &lua_update_instance_timer),
|
||||
luabind::def("get_instance_id", &lua_get_instance_id),
|
||||
luabind::def("get_characters_in_instance", &lua_get_characters_in_instance),
|
||||
luabind::def("assign_to_instance", &lua_assign_to_instance),
|
||||
@@ -1592,6 +1645,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("enable_recipe", &lua_enable_recipe),
|
||||
luabind::def("disable_recipe", &lua_disable_recipe),
|
||||
luabind::def("clear_npctype_cache", &lua_clear_npctype_cache),
|
||||
luabind::def("reloadzonestaticdata", &lua_reloadzonestaticdata),
|
||||
luabind::def("clock", &lua_clock),
|
||||
luabind::def("create_npc", &lua_create_npc),
|
||||
luabind::def("debug", (void(*)(std::string))&lua_debug),
|
||||
@@ -1676,7 +1730,10 @@ luabind::scope lua_register_events() {
|
||||
luabind::value("enter_area", static_cast<int>(EVENT_ENTER_AREA)),
|
||||
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
||||
luabind::value("death_complete", static_cast<int>(EVENT_DEATH_COMPLETE)),
|
||||
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE))
|
||||
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE)),
|
||||
luabind::value("tick", static_cast<int>(EVENT_TICK)),
|
||||
luabind::value("spawn_zone", static_cast<int>(EVENT_SPAWN_ZONE)),
|
||||
luabind::value("death_zone", static_cast<int>(EVENT_DEATH_ZONE))
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1700,50 +1757,50 @@ luabind::scope lua_register_slot() {
|
||||
return luabind::class_<Slots>("Slot")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("Charm", static_cast<int>(MainCharm)),
|
||||
luabind::value("Ear1", static_cast<int>(MainEar1)),
|
||||
luabind::value("Head", static_cast<int>(MainHead)),
|
||||
luabind::value("Face", static_cast<int>(MainFace)),
|
||||
luabind::value("Ear2", static_cast<int>(MainEar2)),
|
||||
luabind::value("Neck", static_cast<int>(MainNeck)),
|
||||
luabind::value("Shoulder", static_cast<int>(MainShoulders)), // deprecated
|
||||
luabind::value("Shoulders", static_cast<int>(MainShoulders)),
|
||||
luabind::value("Arms", static_cast<int>(MainArms)),
|
||||
luabind::value("Back", static_cast<int>(MainBack)),
|
||||
luabind::value("Bracer1", static_cast<int>(MainWrist1)), // deprecated
|
||||
luabind::value("Wrist1", static_cast<int>(MainWrist1)),
|
||||
luabind::value("Bracer2", static_cast<int>(MainWrist2)), // deprecated
|
||||
luabind::value("Wrist2", static_cast<int>(MainWrist2)),
|
||||
luabind::value("Range", static_cast<int>(MainRange)),
|
||||
luabind::value("Hands", static_cast<int>(MainHands)),
|
||||
luabind::value("Primary", static_cast<int>(MainPrimary)),
|
||||
luabind::value("Secondary", static_cast<int>(MainSecondary)),
|
||||
luabind::value("Ring1", static_cast<int>(MainFinger1)), // deprecated
|
||||
luabind::value("Finger1", static_cast<int>(MainFinger1)),
|
||||
luabind::value("Ring2", static_cast<int>(MainFinger2)), // deprecated
|
||||
luabind::value("Finger2", static_cast<int>(MainFinger2)),
|
||||
luabind::value("Chest", static_cast<int>(MainChest)),
|
||||
luabind::value("Legs", static_cast<int>(MainLegs)),
|
||||
luabind::value("Feet", static_cast<int>(MainFeet)),
|
||||
luabind::value("Waist", static_cast<int>(MainWaist)),
|
||||
luabind::value("PowerSource", static_cast<int>(MainPowerSource)),
|
||||
luabind::value("Ammo", static_cast<int>(MainAmmo)),
|
||||
luabind::value("General1", static_cast<int>(MainGeneral1)),
|
||||
luabind::value("General2", static_cast<int>(MainGeneral2)),
|
||||
luabind::value("General3", static_cast<int>(MainGeneral3)),
|
||||
luabind::value("General4", static_cast<int>(MainGeneral4)),
|
||||
luabind::value("General5", static_cast<int>(MainGeneral5)),
|
||||
luabind::value("General6", static_cast<int>(MainGeneral6)),
|
||||
luabind::value("General7", static_cast<int>(MainGeneral7)),
|
||||
luabind::value("General8", static_cast<int>(MainGeneral8)),
|
||||
luabind::value("Cursor", static_cast<int>(MainCursor)),
|
||||
luabind::value("PersonalBegin", static_cast<int>(EmuConstants::GENERAL_BEGIN)), // deprecated
|
||||
luabind::value("GeneralBegin", static_cast<int>(EmuConstants::GENERAL_BEGIN)),
|
||||
luabind::value("PersonalEnd", static_cast<int>(EmuConstants::GENERAL_END)), // deprecated
|
||||
luabind::value("GeneralEnd", static_cast<int>(EmuConstants::GENERAL_END)),
|
||||
luabind::value("Charm", static_cast<int>(EQEmu::legacy::SlotCharm)),
|
||||
luabind::value("Ear1", static_cast<int>(EQEmu::legacy::SlotEar1)),
|
||||
luabind::value("Head", static_cast<int>(EQEmu::legacy::SlotHead)),
|
||||
luabind::value("Face", static_cast<int>(EQEmu::legacy::SlotFace)),
|
||||
luabind::value("Ear2", static_cast<int>(EQEmu::legacy::SlotEar2)),
|
||||
luabind::value("Neck", static_cast<int>(EQEmu::legacy::SlotNeck)),
|
||||
luabind::value("Shoulder", static_cast<int>(EQEmu::legacy::SlotShoulders)), // deprecated
|
||||
luabind::value("Shoulders", static_cast<int>(EQEmu::legacy::SlotShoulders)),
|
||||
luabind::value("Arms", static_cast<int>(EQEmu::legacy::SlotArms)),
|
||||
luabind::value("Back", static_cast<int>(EQEmu::legacy::SlotBack)),
|
||||
luabind::value("Bracer1", static_cast<int>(EQEmu::legacy::SlotWrist1)), // deprecated
|
||||
luabind::value("Wrist1", static_cast<int>(EQEmu::legacy::SlotWrist1)),
|
||||
luabind::value("Bracer2", static_cast<int>(EQEmu::legacy::SlotWrist2)), // deprecated
|
||||
luabind::value("Wrist2", static_cast<int>(EQEmu::legacy::SlotWrist2)),
|
||||
luabind::value("Range", static_cast<int>(EQEmu::legacy::SlotRange)),
|
||||
luabind::value("Hands", static_cast<int>(EQEmu::legacy::SlotHands)),
|
||||
luabind::value("Primary", static_cast<int>(EQEmu::legacy::SlotPrimary)),
|
||||
luabind::value("Secondary", static_cast<int>(EQEmu::legacy::SlotSecondary)),
|
||||
luabind::value("Ring1", static_cast<int>(EQEmu::legacy::SlotFinger1)), // deprecated
|
||||
luabind::value("Finger1", static_cast<int>(EQEmu::legacy::SlotFinger1)),
|
||||
luabind::value("Ring2", static_cast<int>(EQEmu::legacy::SlotFinger2)), // deprecated
|
||||
luabind::value("Finger2", static_cast<int>(EQEmu::legacy::SlotFinger2)),
|
||||
luabind::value("Chest", static_cast<int>(EQEmu::legacy::SlotChest)),
|
||||
luabind::value("Legs", static_cast<int>(EQEmu::legacy::SlotLegs)),
|
||||
luabind::value("Feet", static_cast<int>(EQEmu::legacy::SlotFeet)),
|
||||
luabind::value("Waist", static_cast<int>(EQEmu::legacy::SlotWaist)),
|
||||
luabind::value("PowerSource", static_cast<int>(EQEmu::legacy::SlotPowerSource)),
|
||||
luabind::value("Ammo", static_cast<int>(EQEmu::legacy::SlotAmmo)),
|
||||
luabind::value("General1", static_cast<int>(EQEmu::legacy::SlotGeneral1)),
|
||||
luabind::value("General2", static_cast<int>(EQEmu::legacy::SlotGeneral2)),
|
||||
luabind::value("General3", static_cast<int>(EQEmu::legacy::SlotGeneral3)),
|
||||
luabind::value("General4", static_cast<int>(EQEmu::legacy::SlotGeneral4)),
|
||||
luabind::value("General5", static_cast<int>(EQEmu::legacy::SlotGeneral5)),
|
||||
luabind::value("General6", static_cast<int>(EQEmu::legacy::SlotGeneral6)),
|
||||
luabind::value("General7", static_cast<int>(EQEmu::legacy::SlotGeneral7)),
|
||||
luabind::value("General8", static_cast<int>(EQEmu::legacy::SlotGeneral8)),
|
||||
luabind::value("Cursor", static_cast<int>(EQEmu::legacy::SlotCursor)),
|
||||
luabind::value("PersonalBegin", static_cast<int>(EQEmu::legacy::GENERAL_BEGIN)), // deprecated
|
||||
luabind::value("GeneralBegin", static_cast<int>(EQEmu::legacy::GENERAL_BEGIN)),
|
||||
luabind::value("PersonalEnd", static_cast<int>(EQEmu::legacy::GENERAL_END)), // deprecated
|
||||
luabind::value("GeneralEnd", static_cast<int>(EQEmu::legacy::GENERAL_END)),
|
||||
luabind::value("CursorEnd", 0xFFFE), // deprecated
|
||||
luabind::value("Tradeskill", static_cast<int>(legacy::SLOT_TRADESKILL)), // deprecated
|
||||
luabind::value("Augment", static_cast<int>(legacy::SLOT_AUGMENT)), // deprecated
|
||||
luabind::value("Tradeskill", static_cast<int>(EQEmu::legacy::SLOT_TRADESKILL)), // deprecated
|
||||
luabind::value("Augment", static_cast<int>(EQEmu::legacy::SLOT_AUGMENT)), // deprecated
|
||||
luabind::value("Invalid", INVALID_INDEX)
|
||||
];
|
||||
}
|
||||
@@ -1752,19 +1809,19 @@ luabind::scope lua_register_material() {
|
||||
return luabind::class_<Materials>("Material")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("Head", static_cast<int>(MaterialHead)),
|
||||
luabind::value("Chest", static_cast<int>(MaterialChest)),
|
||||
luabind::value("Arms", static_cast<int>(MaterialArms)),
|
||||
luabind::value("Bracer", static_cast<int>(MaterialWrist)), // deprecated
|
||||
luabind::value("Wrist", static_cast<int>(MaterialWrist)),
|
||||
luabind::value("Hands", static_cast<int>(MaterialHands)),
|
||||
luabind::value("Legs", static_cast<int>(MaterialLegs)),
|
||||
luabind::value("Feet", static_cast<int>(MaterialFeet)),
|
||||
luabind::value("Primary", static_cast<int>(MaterialPrimary)),
|
||||
luabind::value("Secondary", static_cast<int>(MaterialSecondary)),
|
||||
luabind::value("Max", static_cast<int>(_MaterialCount)), // deprecated
|
||||
luabind::value("Count", static_cast<int>(_MaterialCount)),
|
||||
luabind::value("Invalid", static_cast<int>(_MaterialInvalid))
|
||||
luabind::value("Head", static_cast<int>(EQEmu::textures::TextureHead)),
|
||||
luabind::value("Chest", static_cast<int>(EQEmu::textures::TextureChest)),
|
||||
luabind::value("Arms", static_cast<int>(EQEmu::textures::TextureArms)),
|
||||
luabind::value("Bracer", static_cast<int>(EQEmu::textures::TextureWrist)), // deprecated
|
||||
luabind::value("Wrist", static_cast<int>(EQEmu::textures::TextureWrist)),
|
||||
luabind::value("Hands", static_cast<int>(EQEmu::textures::TextureHands)),
|
||||
luabind::value("Legs", static_cast<int>(EQEmu::textures::TextureLegs)),
|
||||
luabind::value("Feet", static_cast<int>(EQEmu::textures::TextureFeet)),
|
||||
luabind::value("Primary", static_cast<int>(EQEmu::textures::TexturePrimary)),
|
||||
luabind::value("Secondary", static_cast<int>(EQEmu::textures::TextureSecondary)),
|
||||
luabind::value("Max", static_cast<int>(EQEmu::textures::TextureCount)), // deprecated
|
||||
luabind::value("Count", static_cast<int>(EQEmu::textures::TextureCount)),
|
||||
luabind::value("Invalid", static_cast<int>(EQEmu::textures::TextureInvalid))
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1772,14 +1829,14 @@ luabind::scope lua_register_client_version() {
|
||||
return luabind::class_<ClientVersions>("ClientVersion")
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("Unknown", static_cast<int>(ClientVersion::Unknown)),
|
||||
luabind::value("Titanium", static_cast<int>(ClientVersion::Titanium)),
|
||||
luabind::value("SoF", static_cast<int>(ClientVersion::SoF)),
|
||||
luabind::value("SoD", static_cast<int>(ClientVersion::SoD)),
|
||||
luabind::value("Underfoot", static_cast<int>(ClientVersion::UF)), // deprecated
|
||||
luabind::value("UF", static_cast<int>(ClientVersion::UF)),
|
||||
luabind::value("RoF", static_cast<int>(ClientVersion::RoF)),
|
||||
luabind::value("RoF2", static_cast<int>(ClientVersion::RoF2))
|
||||
luabind::value("Unknown", static_cast<int>(EQEmu::versions::ClientVersion::Unknown)),
|
||||
luabind::value("Titanium", static_cast<int>(EQEmu::versions::ClientVersion::Titanium)),
|
||||
luabind::value("SoF", static_cast<int>(EQEmu::versions::ClientVersion::SoF)),
|
||||
luabind::value("SoD", static_cast<int>(EQEmu::versions::ClientVersion::SoD)),
|
||||
luabind::value("Underfoot", static_cast<int>(EQEmu::versions::ClientVersion::UF)), // deprecated
|
||||
luabind::value("UF", static_cast<int>(EQEmu::versions::ClientVersion::UF)),
|
||||
luabind::value("RoF", static_cast<int>(EQEmu::versions::ClientVersion::RoF)),
|
||||
luabind::value("RoF2", static_cast<int>(EQEmu::versions::ClientVersion::RoF2))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#include "lua_item.h"
|
||||
|
||||
Lua_Item::Lua_Item(uint32 item_id) {
|
||||
const Item_Struct *t = database.GetItem(item_id);
|
||||
const EQEmu::ItemBase *t = database.GetItem(item_id);
|
||||
SetLuaPtrData(t);
|
||||
}
|
||||
|
||||
|
||||
+9
-6
@@ -4,7 +4,10 @@
|
||||
|
||||
#include "lua_ptr.h"
|
||||
|
||||
struct Item_Struct;
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemBase;
|
||||
}
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
@@ -12,17 +15,17 @@ namespace luabind {
|
||||
|
||||
luabind::scope lua_register_item();
|
||||
|
||||
class Lua_Item : public Lua_Ptr<const Item_Struct>
|
||||
class Lua_Item : public Lua_Ptr<const EQEmu::ItemBase>
|
||||
{
|
||||
typedef const Item_Struct NativeType;
|
||||
typedef const EQEmu::ItemBase NativeType;
|
||||
public:
|
||||
Lua_Item(uint32 item_id);
|
||||
Lua_Item() : Lua_Ptr(nullptr) { }
|
||||
Lua_Item(const Item_Struct *d) : Lua_Ptr(d) { }
|
||||
Lua_Item(const EQEmu::ItemBase *d) : Lua_Ptr(d) { }
|
||||
virtual ~Lua_Item() { }
|
||||
|
||||
operator const Item_Struct*() {
|
||||
return reinterpret_cast<const Item_Struct*>(GetLuaPtrData());
|
||||
operator const EQEmu::ItemBase*() {
|
||||
return reinterpret_cast<const EQEmu::ItemBase*>(GetLuaPtrData());
|
||||
}
|
||||
|
||||
int GetMinStatus();
|
||||
|
||||
@@ -41,7 +41,7 @@ Lua_ItemInst::Lua_ItemInst(const Lua_ItemInst& o) {
|
||||
|
||||
bool Lua_ItemInst::IsType(int item_class) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsType(static_cast<ItemClassTypes>(item_class));
|
||||
return self->IsType(static_cast<EQEmu::item::ItemClass>(item_class));
|
||||
}
|
||||
|
||||
bool Lua_ItemInst::IsStackable() {
|
||||
|
||||
+209
-65
@@ -178,22 +178,22 @@ bool Lua_Mob::Attack(Lua_Mob other, int hand, bool from_riposte, bool is_striket
|
||||
|
||||
void Lua_Mob::Damage(Lua_Mob from, int damage, int spell_id, int attack_skill) {
|
||||
Lua_Safe_Call_Void();
|
||||
return self->Damage(from, damage, spell_id, static_cast<SkillUseTypes>(attack_skill));
|
||||
return self->Damage(from, damage, spell_id, static_cast<EQEmu::skills::SkillType>(attack_skill));
|
||||
}
|
||||
|
||||
void Lua_Mob::Damage(Lua_Mob from, int damage, int spell_id, int attack_skill, bool avoidable) {
|
||||
Lua_Safe_Call_Void();
|
||||
return self->Damage(from, damage, spell_id, static_cast<SkillUseTypes>(attack_skill), avoidable);
|
||||
return self->Damage(from, damage, spell_id, static_cast<EQEmu::skills::SkillType>(attack_skill), avoidable);
|
||||
}
|
||||
|
||||
void Lua_Mob::Damage(Lua_Mob from, int damage, int spell_id, int attack_skill, bool avoidable, int buffslot) {
|
||||
Lua_Safe_Call_Void();
|
||||
return self->Damage(from, damage, spell_id, static_cast<SkillUseTypes>(attack_skill), avoidable, buffslot);
|
||||
return self->Damage(from, damage, spell_id, static_cast<EQEmu::skills::SkillType>(attack_skill), avoidable, buffslot);
|
||||
}
|
||||
|
||||
void Lua_Mob::Damage(Lua_Mob from, int damage, int spell_id, int attack_skill, bool avoidable, int buffslot, bool buff_tic) {
|
||||
Lua_Safe_Call_Void();
|
||||
return self->Damage(from, damage, spell_id, static_cast<SkillUseTypes>(attack_skill), avoidable, buffslot, buff_tic);
|
||||
return self->Damage(from, damage, spell_id, static_cast<EQEmu::skills::SkillType>(attack_skill), avoidable, buffslot, buff_tic);
|
||||
}
|
||||
|
||||
void Lua_Mob::RangedAttack(Lua_Mob other) {
|
||||
@@ -759,28 +759,28 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id) {
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CastSpell(spell_id, target_id, slot);
|
||||
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot));
|
||||
}
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time);
|
||||
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time);
|
||||
}
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost);
|
||||
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost);
|
||||
}
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot));
|
||||
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot));
|
||||
}
|
||||
|
||||
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
|
||||
int timer_duration) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration));
|
||||
}
|
||||
|
||||
@@ -789,8 +789,8 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, in
|
||||
Lua_Safe_Call_Bool();
|
||||
int16 res = resist_adjust;
|
||||
|
||||
return self->CastSpell(spell_id, target_id, slot, cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), 0, &res);
|
||||
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
|
||||
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), &res);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target) {
|
||||
@@ -800,27 +800,27 @@ bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target) {
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SpellFinished(spell_id, target, slot);
|
||||
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot));
|
||||
}
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SpellFinished(spell_id, target, slot, mana_used);
|
||||
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SpellFinished(spell_id, target, slot, mana_used, inventory_slot);
|
||||
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used, inventory_slot);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot, int resist_adjust) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SpellFinished(spell_id, target, slot, mana_used, inventory_slot, resist_adjust);
|
||||
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used, inventory_slot, resist_adjust);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot, int resist_adjust, bool proc) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SpellFinished(spell_id, target, slot, mana_used, inventory_slot, resist_adjust, proc);
|
||||
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used, inventory_slot, resist_adjust, proc);
|
||||
}
|
||||
|
||||
void Lua_Mob::SpellEffect(Lua_Mob caster, int spell_id, double partial) {
|
||||
@@ -1023,14 +1023,14 @@ int Lua_Mob::GetHaste() {
|
||||
return self->GetHaste();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetMonkHandToHandDamage() {
|
||||
int Lua_Mob::GetHandToHandDamage() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMonkHandToHandDamage();
|
||||
return self->GetHandToHandDamage();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetMonkHandToHandDelay() {
|
||||
int Lua_Mob::GetHandToHandDelay() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMonkHandToHandDelay();
|
||||
return self->GetHandToHandDelay();
|
||||
}
|
||||
|
||||
void Lua_Mob::Mesmerize() {
|
||||
@@ -1172,22 +1172,22 @@ bool Lua_Mob::Charmed() {
|
||||
|
||||
int Lua_Mob::CheckAggroAmount(int spell_id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->CheckAggroAmount(spell_id);
|
||||
return self->CheckAggroAmount(spell_id, nullptr);
|
||||
}
|
||||
|
||||
int Lua_Mob::CheckAggroAmount(int spell_id, bool is_proc) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->CheckAggroAmount(spell_id, is_proc);
|
||||
return self->CheckAggroAmount(spell_id, nullptr, is_proc);
|
||||
}
|
||||
|
||||
int Lua_Mob::CheckHealAggroAmount(int spell_id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->CheckHealAggroAmount(spell_id);
|
||||
return self->CheckHealAggroAmount(spell_id, nullptr);
|
||||
}
|
||||
|
||||
int Lua_Mob::CheckHealAggroAmount(int spell_id, uint32 heal_possible) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->CheckHealAggroAmount(spell_id, heal_possible);
|
||||
return self->CheckHealAggroAmount(spell_id, nullptr, heal_possible);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetAA(int id) {
|
||||
@@ -1195,6 +1195,21 @@ int Lua_Mob::GetAA(int id) {
|
||||
return self->GetAA(id);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetAAByAAID(int id) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAAByAAID(id);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SetAA(int rank_id, int new_value) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SetAA(rank_id, new_value);
|
||||
}
|
||||
|
||||
bool Lua_Mob::SetAA(int rank_id, int new_value, int charges) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SetAA(rank_id, new_value, charges);
|
||||
}
|
||||
|
||||
bool Lua_Mob::DivineAura() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->DivineAura();
|
||||
@@ -1237,28 +1252,28 @@ bool Lua_Mob::CombatRange(Lua_Mob other) {
|
||||
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage);
|
||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage);
|
||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override);
|
||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage, hate_override);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override, reuse_time);
|
||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage, hate_override, reuse_time);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage, int hate_override, int reuse_time,
|
||||
bool hit_chance) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoSpecialAttackDamage(other, static_cast<SkillUseTypes>(skill), max_damage, min_damage, hate_override, reuse_time, hit_chance);
|
||||
self->DoSpecialAttackDamage(other, static_cast<EQEmu::skills::SkillType>(skill), max_damage, min_damage, hate_override, reuse_time, hit_chance);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other) {
|
||||
@@ -1294,22 +1309,22 @@ void Lua_Mob::DoThrowingAttackDmg(Lua_Mob other, Lua_ItemInst range_weapon, Lua_
|
||||
|
||||
void Lua_Mob::DoMeleeSkillAttackDmg(Lua_Mob other, int weapon_damage, int skill) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<SkillUseTypes>(skill));
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<EQEmu::skills::SkillType>(skill));
|
||||
}
|
||||
|
||||
void Lua_Mob::DoMeleeSkillAttackDmg(Lua_Mob other, int weapon_damage, int skill, int chance_mod) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<SkillUseTypes>(skill), chance_mod);
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<EQEmu::skills::SkillType>(skill), chance_mod);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoMeleeSkillAttackDmg(Lua_Mob other, int weapon_damage, int skill, int chance_mod, int focus) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<SkillUseTypes>(skill), chance_mod, focus);
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<EQEmu::skills::SkillType>(skill), chance_mod, focus);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoMeleeSkillAttackDmg(Lua_Mob other, int weapon_damage, int skill, int chance_mod, int focus, bool can_riposte) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<SkillUseTypes>(skill), chance_mod, focus, can_riposte);
|
||||
self->DoMeleeSkillAttackDmg(other, weapon_damage, static_cast<EQEmu::skills::SkillType>(skill), chance_mod, focus, can_riposte);
|
||||
}
|
||||
|
||||
void Lua_Mob::DoArcheryAttackDmg(Lua_Mob other) {
|
||||
@@ -1590,26 +1605,6 @@ void Lua_Mob::SendIllusionPacket(luabind::adl::object illusion) {
|
||||
beard, aa_title, drakkin_heritage, drakkin_tattoo, drakkin_details, size);
|
||||
}
|
||||
|
||||
void Lua_Mob::QuestReward(Lua_Client c) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(c);
|
||||
}
|
||||
|
||||
void Lua_Mob::QuestReward(Lua_Client c, uint32 silver) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(c, silver);
|
||||
}
|
||||
|
||||
void Lua_Mob::QuestReward(Lua_Client c, uint32 silver, uint32 gold) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(c, silver, gold);
|
||||
}
|
||||
|
||||
void Lua_Mob::QuestReward(Lua_Client c, uint32 silver, uint32 gold, uint32 platinum) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->QuestReward(c, silver, gold, platinum);
|
||||
}
|
||||
|
||||
void Lua_Mob::CameraEffect(uint32 duration, uint32 intensity) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->CameraEffect(duration, intensity);
|
||||
@@ -1651,6 +1646,11 @@ void Lua_Mob::TempName(const char *newname) {
|
||||
self->TempName(newname);
|
||||
}
|
||||
|
||||
std::string Lua_Mob::GetGlobal(const char *varname) {
|
||||
Lua_Safe_Call_String();
|
||||
return self->GetGlobal(varname);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetGlobal(const char *varname, const char *newvalue, int options, const char *duration) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetGlobal(varname, newvalue, options, duration);
|
||||
@@ -1713,17 +1713,17 @@ void Lua_Mob::SetTargetable(bool on) {
|
||||
|
||||
void Lua_Mob::ModSkillDmgTaken(int skill, int value) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ModSkillDmgTaken(static_cast<SkillUseTypes>(skill), value);
|
||||
self->ModSkillDmgTaken(static_cast<EQEmu::skills::SkillType>(skill), value);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetModSkillDmgTaken(int skill) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetModSkillDmgTaken(static_cast<SkillUseTypes>(skill));
|
||||
return self->GetModSkillDmgTaken(static_cast<EQEmu::skills::SkillType>(skill));
|
||||
}
|
||||
|
||||
int Lua_Mob::GetSkillDmgTaken(int skill) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetSkillDmgTaken(static_cast<SkillUseTypes>(skill));
|
||||
return self->GetSkillDmgTaken(static_cast<EQEmu::skills::SkillType>(skill));
|
||||
}
|
||||
|
||||
void Lua_Mob::SetAllowBeneficial(bool value) {
|
||||
@@ -1773,7 +1773,7 @@ int Lua_Mob::GetFlurryChance() {
|
||||
|
||||
int Lua_Mob::GetSkill(int skill) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetSkill(static_cast<SkillUseTypes>(skill));
|
||||
return self->GetSkill(static_cast<EQEmu::skills::SkillType>(skill));
|
||||
}
|
||||
|
||||
int Lua_Mob::GetSpecialAbility(int ability) {
|
||||
@@ -1866,6 +1866,120 @@ int Lua_Mob::CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite
|
||||
return self->CanBuffStack(spell_id, caster_level, fail_if_overwrite);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetPseudoRoot(bool in) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetPseudoRoot(in);
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsFeared() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsFeared();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsBlind() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsBlind();
|
||||
}
|
||||
|
||||
uint8 Lua_Mob::SeeInvisible() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->SeeInvisible();
|
||||
}
|
||||
|
||||
bool Lua_Mob::SeeInvisibleUndead() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SeeInvisibleUndead();
|
||||
}
|
||||
|
||||
bool Lua_Mob::SeeHide() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SeeHide();
|
||||
}
|
||||
|
||||
bool Lua_Mob::SeeImprovedHide() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->SeeImprovedHide();
|
||||
}
|
||||
|
||||
uint8 Lua_Mob::GetNimbusEffect1() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetNimbusEffect1();
|
||||
}
|
||||
|
||||
uint8 Lua_Mob::GetNimbusEffect2() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetNimbusEffect2();
|
||||
}
|
||||
|
||||
uint8 Lua_Mob::GetNimbusEffect3() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetNimbusEffect3();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsTargetable() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsTargetable();
|
||||
}
|
||||
|
||||
bool Lua_Mob::HasShieldEquiped() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasShieldEquiped();
|
||||
}
|
||||
|
||||
bool Lua_Mob::HasTwoHandBluntEquiped() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasTwoHandBluntEquiped();
|
||||
}
|
||||
|
||||
bool Lua_Mob::HasTwoHanderEquipped() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasTwoHanderEquipped();
|
||||
}
|
||||
|
||||
uint32 Lua_Mob::GetHerosForgeModel(uint8 material_slot) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetHerosForgeModel(material_slot);
|
||||
}
|
||||
|
||||
uint32 Lua_Mob::IsEliteMaterialItem(uint8 material_slot) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->IsEliteMaterialItem(material_slot);
|
||||
}
|
||||
|
||||
float Lua_Mob::GetBaseSize() {
|
||||
Lua_Safe_Call_Real();
|
||||
return self->GetBaseSize();
|
||||
}
|
||||
|
||||
bool Lua_Mob::HasOwner() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasOwner();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsPet() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsPet();
|
||||
}
|
||||
|
||||
bool Lua_Mob::HasPet() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasPet();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsSilenced() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsSilenced();
|
||||
}
|
||||
|
||||
bool Lua_Mob::IsAmnesiad() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsAmnesiad();
|
||||
}
|
||||
|
||||
int32 Lua_Mob::GetMeleeMitigation() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMeleeMitigation();
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob() {
|
||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||
@@ -2051,8 +2165,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetInvul", (bool(Lua_Mob::*)(void))&Lua_Mob::GetInvul)
|
||||
.def("SetExtraHaste", (void(Lua_Mob::*)(int))&Lua_Mob::SetExtraHaste)
|
||||
.def("GetHaste", (int(Lua_Mob::*)(void))&Lua_Mob::GetHaste)
|
||||
.def("GetMonkHandToHandDamage", (int(Lua_Mob::*)(void))&Lua_Mob::GetMonkHandToHandDamage)
|
||||
.def("GetMonkHandToHandDelay", (int(Lua_Mob::*)(void))&Lua_Mob::GetMonkHandToHandDelay)
|
||||
.def("GetHandToHandDamage", (int(Lua_Mob::*)(void))&Lua_Mob::GetHandToHandDamage)
|
||||
.def("GetHandToHandDelay", (int(Lua_Mob::*)(void))&Lua_Mob::GetHandToHandDelay)
|
||||
.def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize)
|
||||
.def("IsMezzed", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMezzed)
|
||||
.def("IsEnraged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEnraged)
|
||||
@@ -2085,6 +2199,9 @@ luabind::scope lua_register_mob() {
|
||||
.def("CheckHealAggroAmount", (int(Lua_Mob::*)(int))&Lua_Mob::CheckHealAggroAmount)
|
||||
.def("CheckHealAggroAmount", (int(Lua_Mob::*)(int,uint32))&Lua_Mob::CheckHealAggroAmount)
|
||||
.def("GetAA", (int(Lua_Mob::*)(int))&Lua_Mob::GetAA)
|
||||
.def("GetAAByAAID", (int(Lua_Mob::*)(int))&Lua_Mob::GetAAByAAID)
|
||||
.def("SetAA", (bool(Lua_Mob::*)(int,int))&Lua_Mob::SetAA)
|
||||
.def("SetAA", (bool(Lua_Mob::*)(int,int,int))&Lua_Mob::SetAA)
|
||||
.def("DivineAura", (bool(Lua_Mob::*)(void))&Lua_Mob::DivineAura)
|
||||
.def("SetOOCRegen", (void(Lua_Mob::*)(int))&Lua_Mob::SetOOCRegen)
|
||||
.def("GetEntityVariable", (const char*(Lua_Mob::*)(const char*))&Lua_Mob::GetEntityVariable)
|
||||
@@ -2132,10 +2249,6 @@ luabind::scope lua_register_mob() {
|
||||
.def("SetRace", (void(Lua_Mob::*)(int))&Lua_Mob::SetRace)
|
||||
.def("SetGender", (void(Lua_Mob::*)(int))&Lua_Mob::SetGender)
|
||||
.def("SendIllusionPacket", (void(Lua_Mob::*)(luabind::adl::object))&Lua_Mob::SendIllusionPacket)
|
||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client))&Lua_Mob::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client,uint32))&Lua_Mob::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client,uint32,uint32))&Lua_Mob::QuestReward)
|
||||
.def("QuestReward", (void(Lua_Mob::*)(Lua_Client,uint32,uint32,uint32))&Lua_Mob::QuestReward)
|
||||
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32))&Lua_Mob::CameraEffect)
|
||||
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32,Lua_Client))&Lua_Mob::CameraEffect)
|
||||
.def("CameraEffect", (void(Lua_Mob::*)(uint32,uint32,Lua_Client,bool))&Lua_Mob::CameraEffect)
|
||||
@@ -2144,6 +2257,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("SendSpellEffect", (void(Lua_Mob::*)(uint32,uint32,uint32,bool,uint32,bool,Lua_Client))&Lua_Mob::SendSpellEffect)
|
||||
.def("TempName", (void(Lua_Mob::*)(void))&Lua_Mob::TempName)
|
||||
.def("TempName", (void(Lua_Mob::*)(const char*))&Lua_Mob::TempName)
|
||||
.def("GetGlobal", (std::string(Lua_Mob::*)(const char*))&Lua_Mob::GetGlobal)
|
||||
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*))&Lua_Mob::SetGlobal)
|
||||
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*,Lua_Mob))&Lua_Mob::SetGlobal)
|
||||
.def("TarGlobal", (void(Lua_Mob::*)(const char*,const char*,const char*,int,int,int))&Lua_Mob::TarGlobal)
|
||||
@@ -2152,6 +2266,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("WearChange", (void(Lua_Mob::*)(int,int,uint32))&Lua_Mob::WearChange)
|
||||
.def("DoKnockback", (void(Lua_Mob::*)(Lua_Mob,uint32,uint32))&Lua_Mob::DoKnockback)
|
||||
.def("RemoveNimbusEffect", (void(Lua_Mob::*)(int))&Lua_Mob::RemoveNimbusEffect)
|
||||
.def("IsFeared", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFeared)
|
||||
.def("IsBlind", (bool(Lua_Mob::*)(void))&Lua_Mob::IsBlind)
|
||||
.def("IsRunning", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRunning)
|
||||
.def("SetRunning", (void(Lua_Mob::*)(bool))&Lua_Mob::SetRunning)
|
||||
.def("SetBodyType", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetBodyType)
|
||||
@@ -2186,7 +2302,28 @@ luabind::scope lua_register_mob() {
|
||||
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int))&Lua_Mob::BuffFadeBySlot)
|
||||
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot)
|
||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int))&Lua_Mob::CanBuffStack)
|
||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack);
|
||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack)
|
||||
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot)
|
||||
.def("SeeInvisible", (uint8(Lua_Mob::*)(void))&Lua_Mob::SeeInvisible)
|
||||
.def("SeeInvisibleUndead", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeInvisibleUndead)
|
||||
.def("SeeHide", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeHide)
|
||||
.def("SeeImprovedHide", (bool(Lua_Mob::*)(bool))&Lua_Mob::SeeImprovedHide)
|
||||
.def("GetNimbusEffect1", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetNimbusEffect1)
|
||||
.def("GetNimbusEffect2", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetNimbusEffect2)
|
||||
.def("GetNimbusEffect3", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetNimbusEffect3)
|
||||
.def("IsTargetable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTargetable)
|
||||
.def("HasShieldEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasShieldEquiped)
|
||||
.def("HasTwoHandBluntEquiped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHandBluntEquiped)
|
||||
.def("HasTwoHanderEquipped", (bool(Lua_Mob::*)(void))&Lua_Mob::HasTwoHanderEquipped)
|
||||
.def("GetHerosForgeModel", (int32(Lua_Mob::*)(uint8))&Lua_Mob::GetHerosForgeModel)
|
||||
.def("IsEliteMaterialItem", (uint32(Lua_Mob::*)(uint8))&Lua_Mob::IsEliteMaterialItem)
|
||||
.def("GetBaseSize", (double(Lua_Mob::*)(void))&Lua_Mob::GetBaseSize)
|
||||
.def("HasOwner", (bool(Lua_Mob::*)(void))&Lua_Mob::HasOwner)
|
||||
.def("IsPet", (bool(Lua_Mob::*)(void))&Lua_Mob::IsPet)
|
||||
.def("HasPet", (bool(Lua_Mob::*)(void))&Lua_Mob::HasPet)
|
||||
.def("IsSilenced", (bool(Lua_Mob::*)(void))&Lua_Mob::IsSilenced)
|
||||
.def("IsAmnesiad", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAmnesiad)
|
||||
.def("GetMeleeMitigation", (int32(Lua_Mob::*)(void))&Lua_Mob::GetMeleeMitigation);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_special_abilities() {
|
||||
@@ -2229,7 +2366,14 @@ luabind::scope lua_register_special_abilities() {
|
||||
luabind::value("destructible_object", static_cast<int>(DESTRUCTIBLE_OBJECT)),
|
||||
luabind::value("no_harm_from_client", static_cast<int>(NO_HARM_FROM_CLIENT)),
|
||||
luabind::value("always_flee", static_cast<int>(ALWAYS_FLEE)),
|
||||
luabind::value("flee_percent", static_cast<int>(FLEE_PERCENT))
|
||||
luabind::value("flee_percent", static_cast<int>(FLEE_PERCENT)),
|
||||
luabind::value("allow_beneficial", static_cast<int>(ALLOW_BENEFICIAL)),
|
||||
luabind::value("disable_melee", static_cast<int>(DISABLE_MELEE)),
|
||||
luabind::value("npc_chase_distance", static_cast<int>(NPC_CHASE_DISTANCE)),
|
||||
luabind::value("allow_to_tank", static_cast<int>(ALLOW_TO_TANK)),
|
||||
luabind::value("ignore_root_aggro_rules", static_cast<int>(IGNORE_ROOT_AGGRO_RULES)),
|
||||
luabind::value("casting_resist_diff", static_cast<int>(CASTING_RESIST_DIFF)),
|
||||
luabind::value("counter_avoid_damage", static_cast<int>(COUNTER_AVOID_DAMAGE))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+33
-8
@@ -11,7 +11,9 @@ class Lua_ItemInst;
|
||||
|
||||
namespace luabind {
|
||||
struct scope;
|
||||
class object;
|
||||
namespace adl {
|
||||
class object;
|
||||
}
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob();
|
||||
@@ -40,6 +42,8 @@ public:
|
||||
void SetLevel(int level, bool command);
|
||||
void SendWearChange(int material_slot);
|
||||
bool IsMoving();
|
||||
bool IsFeared();
|
||||
bool IsBlind();
|
||||
void GotoBind();
|
||||
void Gate();
|
||||
bool Attack(Lua_Mob other);
|
||||
@@ -169,7 +173,7 @@ public:
|
||||
bool CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost);
|
||||
bool CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot);
|
||||
bool CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, int timer_duration);
|
||||
bool CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, int timer_duration,
|
||||
bool CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer, int timer_duration,
|
||||
int resist_adjust);
|
||||
bool SpellFinished(int spell_id, Lua_Mob target);
|
||||
bool SpellFinished(int spell_id, Lua_Mob target, int slot);
|
||||
@@ -215,8 +219,8 @@ public:
|
||||
bool GetInvul();
|
||||
void SetExtraHaste(int haste);
|
||||
int GetHaste();
|
||||
int GetMonkHandToHandDamage();
|
||||
int GetMonkHandToHandDelay();
|
||||
int GetHandToHandDamage();
|
||||
int GetHandToHandDelay();
|
||||
void Mesmerize();
|
||||
bool IsMezzed();
|
||||
bool IsEnraged();
|
||||
@@ -249,6 +253,9 @@ public:
|
||||
int CheckHealAggroAmount(int spell_id);
|
||||
int CheckHealAggroAmount(int spell_id, uint32 heal_possible);
|
||||
int GetAA(int id);
|
||||
int GetAAByAAID(int id);
|
||||
bool SetAA(int rank_id, int new_value);
|
||||
bool SetAA(int rank_id, int new_value, int charges);
|
||||
bool DivineAura();
|
||||
void SetOOCRegen(int regen);
|
||||
const char* GetEntityVariable(const char *name);
|
||||
@@ -296,10 +303,6 @@ public:
|
||||
void SetRace(int in);
|
||||
void SetGender(int in);
|
||||
void SendIllusionPacket(luabind::adl::object illusion);
|
||||
void QuestReward(Lua_Client c);
|
||||
void QuestReward(Lua_Client c, uint32 silver);
|
||||
void QuestReward(Lua_Client c, uint32 silver, uint32 gold);
|
||||
void QuestReward(Lua_Client c, uint32 silver, uint32 gold, uint32 platinum);
|
||||
void CameraEffect(uint32 duration, uint32 intensity);
|
||||
void CameraEffect(uint32 duration, uint32 intensity, Lua_Client c);
|
||||
void CameraEffect(uint32 duration, uint32 intensity, Lua_Client c, bool global);
|
||||
@@ -311,6 +314,7 @@ public:
|
||||
uint32 unk020, bool perm_effect, Lua_Client c);
|
||||
void TempName();
|
||||
void TempName(const char *newname);
|
||||
std::string GetGlobal(const char *varname);
|
||||
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration);
|
||||
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Lua_Mob other);
|
||||
void TarGlobal(const char *varname, const char *value, const char *duration, int npc_id, int char_id, int zone_id);
|
||||
@@ -355,6 +359,27 @@ public:
|
||||
void BuffFadeBySlot(int slot, bool recalc_bonuses);
|
||||
int CanBuffStack(int spell_id, int caster_level);
|
||||
int CanBuffStack(int spell_id, int caster_level, bool fail_if_overwrite);
|
||||
void SetPseudoRoot(bool in);
|
||||
uint8 SeeInvisible();
|
||||
bool SeeInvisibleUndead();
|
||||
bool SeeHide();
|
||||
bool SeeImprovedHide();
|
||||
uint8 GetNimbusEffect1();
|
||||
uint8 GetNimbusEffect2();
|
||||
uint8 GetNimbusEffect3();
|
||||
bool IsTargetable();
|
||||
bool HasShieldEquiped();
|
||||
bool HasTwoHandBluntEquiped();
|
||||
bool HasTwoHanderEquipped();
|
||||
uint32 GetHerosForgeModel(uint8 material_slot);
|
||||
uint32 IsEliteMaterialItem(uint8 material_slot);
|
||||
float GetBaseSize();
|
||||
bool HasOwner();
|
||||
bool IsPet();
|
||||
bool HasPet();
|
||||
bool IsSilenced();
|
||||
bool IsAmnesiad();
|
||||
int32 GetMeleeMitigation();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -428,6 +428,11 @@ float Lua_NPC::GetAttackSpeed() {
|
||||
return self->GetAttackSpeed();
|
||||
}
|
||||
|
||||
int Lua_NPC::GetAttackDelay() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAttackDelay();
|
||||
}
|
||||
|
||||
int Lua_NPC::GetAccuracyRating() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAccuracyRating();
|
||||
@@ -550,6 +555,7 @@ luabind::scope lua_register_npc() {
|
||||
.def("GetSpellFocusHeal", (void(Lua_NPC::*)(int))&Lua_NPC::GetSpellFocusHeal)
|
||||
.def("GetSlowMitigation", (int(Lua_NPC::*)(void))&Lua_NPC::GetSlowMitigation)
|
||||
.def("GetAttackSpeed", (float(Lua_NPC::*)(void))&Lua_NPC::GetAttackSpeed)
|
||||
.def("GetAttackDelay", (int(Lua_NPC::*)(void))&Lua_NPC::GetAttackDelay)
|
||||
.def("GetAccuracyRating", (int(Lua_NPC::*)(void))&Lua_NPC::GetAccuracyRating)
|
||||
.def("GetSpawnKillCount", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnKillCount)
|
||||
.def("GetScore", (int(Lua_NPC::*)(void))&Lua_NPC::GetScore)
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
int GetSpellFocusHeal();
|
||||
float GetSlowMitigation();
|
||||
float GetAttackSpeed();
|
||||
int GetAttackDelay();
|
||||
int GetAccuracyRating();
|
||||
int GetSpawnKillCount();
|
||||
int GetScore();
|
||||
|
||||
+5
-4
@@ -18,7 +18,7 @@ Lua_Packet::Lua_Packet(int opcode, int size, bool raw) {
|
||||
if(raw) {
|
||||
SetLuaPtrData(new EQApplicationPacket(OP_Unknown, size));
|
||||
owned_ = true;
|
||||
|
||||
|
||||
EQApplicationPacket *self = reinterpret_cast<EQApplicationPacket*>(d_);
|
||||
self->SetOpcodeBypass(opcode);
|
||||
} else {
|
||||
@@ -692,8 +692,8 @@ luabind::scope lua_register_packet_opcodes() {
|
||||
luabind::value("VetClaimRequest", static_cast<int>(OP_VetClaimRequest)),
|
||||
luabind::value("VetClaimReply", static_cast<int>(OP_VetClaimReply)),
|
||||
luabind::value("WeaponEquip1", static_cast<int>(OP_WeaponEquip1)),
|
||||
luabind::value("WeaponEquip2", static_cast<int>(OP_WeaponEquip2)),
|
||||
luabind::value("WeaponUnequip2", static_cast<int>(OP_WeaponUnequip2)),
|
||||
luabind::value("PlayerStateAdd", static_cast<int>(OP_PlayerStateAdd)),
|
||||
luabind::value("PlayerStateRemove", static_cast<int>(OP_PlayerStateRemove)),
|
||||
luabind::value("WorldLogout", static_cast<int>(OP_WorldLogout)),
|
||||
luabind::value("SessionReady", static_cast<int>(OP_SessionReady)),
|
||||
luabind::value("Login", static_cast<int>(OP_Login)),
|
||||
@@ -847,7 +847,8 @@ luabind::scope lua_register_packet_opcodes() {
|
||||
luabind::value("OpenContainer", static_cast<int>(OP_OpenContainer)),
|
||||
luabind::value("Marquee", static_cast<int>(OP_Marquee)),
|
||||
luabind::value("ClientTimeStamp", static_cast<int>(OP_ClientTimeStamp)),
|
||||
luabind::value("GuildPromote", static_cast<int>(OP_GuildPromote))
|
||||
luabind::value("GuildPromote", static_cast<int>(OP_GuildPromote)),
|
||||
luabind::value("Fling", static_cast<int>(OP_Fling))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+98
-47
@@ -33,7 +33,9 @@
|
||||
#include "lua_general.h"
|
||||
#include "questmgr.h"
|
||||
#include "zone.h"
|
||||
#include "zone_config.h"
|
||||
#include "lua_parser.h"
|
||||
#include "lua_encounter.h"
|
||||
|
||||
const char *LuaEvents[_LargestEventID] = {
|
||||
"event_say",
|
||||
@@ -115,7 +117,10 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_leave_area",
|
||||
"event_respawn",
|
||||
"event_death_complete",
|
||||
"event_unhandled_opcode"
|
||||
"event_unhandled_opcode",
|
||||
"event_tick",
|
||||
"event_spawn_zone",
|
||||
"event_death_zone"
|
||||
};
|
||||
|
||||
extern Zone *zone;
|
||||
@@ -128,6 +133,7 @@ struct lua_registered_event {
|
||||
|
||||
std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
|
||||
std::map<std::string, bool> lua_encounters_loaded;
|
||||
std::map<std::string, Encounter *> lua_encounters;
|
||||
|
||||
LuaParser::LuaParser() {
|
||||
for(int i = 0; i < _LargestEventID; ++i) {
|
||||
@@ -135,6 +141,7 @@ LuaParser::LuaParser() {
|
||||
PlayerArgumentDispatch[i] = handle_player_null;
|
||||
ItemArgumentDispatch[i] = handle_item_null;
|
||||
SpellArgumentDispatch[i] = handle_spell_null;
|
||||
EncounterArgumentDispatch[i] = handle_encounter_null;
|
||||
}
|
||||
|
||||
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
|
||||
@@ -213,6 +220,10 @@ LuaParser::LuaParser() {
|
||||
SpellArgumentDispatch[EVENT_SPELL_FADE] = handle_spell_fade;
|
||||
SpellArgumentDispatch[EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE] = handle_translocate_finish;
|
||||
|
||||
EncounterArgumentDispatch[EVENT_TIMER] = handle_encounter_timer;
|
||||
EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load;
|
||||
EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload;
|
||||
|
||||
L = nullptr;
|
||||
}
|
||||
|
||||
@@ -274,7 +285,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 2;
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//always push self
|
||||
Lua_NPC l_npc(npc);
|
||||
@@ -285,7 +296,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
auto arg_function = NPCArgumentDispatch[evt];
|
||||
arg_function(this, L, npc, init, data, extra_data, extra_pointers);
|
||||
Client *c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
|
||||
|
||||
|
||||
quest_manager.StartQuest(npc, c, nullptr);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@@ -294,13 +305,13 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@@ -368,17 +379,17 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 2;
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//push self
|
||||
Lua_Client l_client(client);
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "self");
|
||||
|
||||
|
||||
auto arg_function = PlayerArgumentDispatch[evt];
|
||||
arg_function(this, L, client, data, extra_data, extra_pointers);
|
||||
|
||||
|
||||
quest_manager.StartQuest(client, client, nullptr);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@@ -387,13 +398,13 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@@ -417,15 +428,15 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *
|
||||
if(evt >= _LargestEventID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!item) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!ItemHasQuestSub(item, evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string package_name = "item_";
|
||||
package_name += std::to_string(item->GetID());
|
||||
return _EventItem(package_name, evt, client, item, mob, data, extra_data, extra_pointers);
|
||||
@@ -445,7 +456,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
|
||||
lua_getfield(L, -1, sub_name);
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//always push self
|
||||
Lua_ItemInst l_item(item);
|
||||
@@ -461,7 +472,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
//redo this arg function
|
||||
auto arg_function = ItemArgumentDispatch[evt];
|
||||
arg_function(this, L, client, item, mob, data, extra_data, extra_pointers);
|
||||
|
||||
|
||||
quest_manager.StartQuest(client, client, item);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@@ -470,13 +481,13 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@@ -513,7 +524,7 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe
|
||||
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) {
|
||||
const char *sub_name = LuaEvents[evt];
|
||||
|
||||
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
@@ -525,7 +536,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 2;
|
||||
}
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
|
||||
//always push self even if invalid
|
||||
@@ -539,10 +550,10 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
l_spell_o.push(L);
|
||||
}
|
||||
lua_setfield(L, -2, "self");
|
||||
|
||||
|
||||
auto arg_function = SpellArgumentDispatch[evt];
|
||||
arg_function(this, L, npc, client, spell_id, extra_data, extra_pointers);
|
||||
|
||||
|
||||
quest_manager.StartQuest(npc, client, nullptr);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
@@ -551,13 +562,13 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@@ -575,7 +586,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers) {
|
||||
int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers) {
|
||||
evt = ConvertLuaEvent(evt);
|
||||
if(evt >= _LargestEventID) {
|
||||
return 0;
|
||||
@@ -586,31 +597,30 @@ int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint
|
||||
if(!EncounterHasQuestSub(encounter_name, evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _EventEncounter(package_name, evt, encounter_name, extra_data, extra_pointers);
|
||||
|
||||
return _EventEncounter(package_name, evt, encounter_name, data, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
const char *sub_name = LuaEvents[evt];
|
||||
|
||||
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
|
||||
lua_getfield(L, -1, sub_name);
|
||||
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
lua_pushstring(L, encounter_name.c_str());
|
||||
lua_setfield(L, -2, "name");
|
||||
|
||||
if(extra_pointers) {
|
||||
std::string *str = EQEmu::any_cast<std::string*>(extra_pointers->at(0));
|
||||
lua_pushstring(L, str->c_str());
|
||||
lua_setfield(L, -2, "data");
|
||||
}
|
||||
Encounter *enc = lua_encounters[encounter_name];
|
||||
|
||||
quest_manager.StartQuest(nullptr, nullptr, nullptr, encounter_name);
|
||||
auto arg_function = EncounterArgumentDispatch[evt];
|
||||
arg_function(this, L, enc, data, extra_data, extra_pointers);
|
||||
|
||||
quest_manager.StartQuest(enc, nullptr, nullptr, encounter_name);
|
||||
if(lua_pcall(L, 1, 1, 0)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@@ -618,13 +628,13 @@ int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, 2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
lua_pop(L, 2);
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = "Lua Exception: ";
|
||||
@@ -786,6 +796,11 @@ void LuaParser::ReloadQuests() {
|
||||
lua_encounter_events_registered.clear();
|
||||
lua_encounters_loaded.clear();
|
||||
|
||||
for (auto encounter : lua_encounters) {
|
||||
encounter.second->Depop();
|
||||
}
|
||||
lua_encounters.clear();
|
||||
|
||||
if(L) {
|
||||
lua_close(L);
|
||||
}
|
||||
@@ -832,37 +847,71 @@ void LuaParser::ReloadQuests() {
|
||||
lua_pushnil(L);
|
||||
lua_setglobal(L, "loadfile");
|
||||
|
||||
#endif
|
||||
|
||||
// lua 5.2+ defines these
|
||||
#if defined(LUA_VERSION_MAJOR) && defined(LUA_VERSION_MINOR)
|
||||
const char lua_version[] = LUA_VERSION_MAJOR "." LUA_VERSION_MINOR;
|
||||
#elif LUA_VERSION_NUM == 501
|
||||
const char lua_version[] = "5.1";
|
||||
#else
|
||||
#error Incompatible lua version
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
const char libext[] = ".dll";
|
||||
#else
|
||||
// lua doesn't care OSX doesn't use sonames
|
||||
const char libext[] = ".so";
|
||||
#endif
|
||||
|
||||
lua_getglobal(L, "package");
|
||||
lua_getfield(L, -1, "path");
|
||||
std::string module_path = lua_tostring(L,-1);
|
||||
module_path += ";./lua_modules/?.lua";
|
||||
module_path += ";./" + Config->LuaModuleDir + "?.lua;./" + Config->LuaModuleDir + "?/init.lua";
|
||||
// luarock paths using lua_modules as tree
|
||||
// to path it adds foo/share/lua/5.1/?.lua and foo/share/lua/5.1/?/init.lua
|
||||
module_path += ";./" + Config->LuaModuleDir + "share/lua/" + lua_version + "/?.lua";
|
||||
module_path += ";./" + Config->LuaModuleDir + "share/lua/" + lua_version + "/?/init.lua";
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, module_path.c_str());
|
||||
lua_setfield(L, -2, "path");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getglobal(L, "package");
|
||||
lua_getfield(L, -1, "cpath");
|
||||
module_path = lua_tostring(L, -1);
|
||||
module_path += ";./" + Config->LuaModuleDir + "?" + libext;
|
||||
// luarock paths using lua_modules as tree
|
||||
// luarocks adds foo/lib/lua/5.1/?.so for cpath
|
||||
module_path += ";./" + Config->LuaModuleDir + "lib/lua/" + lua_version + "/?" + libext;
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, module_path.c_str());
|
||||
lua_setfield(L, -2, "cpath");
|
||||
lua_pop(L, 1);
|
||||
|
||||
MapFunctions(L);
|
||||
|
||||
//load init
|
||||
std::string path = "quests/";
|
||||
std::string path = Config->QuestDir;
|
||||
path += "/";
|
||||
path += QUEST_GLOBAL_DIRECTORY;
|
||||
path += "/script_init.lua";
|
||||
|
||||
FILE *f = fopen(path.c_str(), "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
|
||||
|
||||
if(luaL_dofile(L, path.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//zone init - always loads after global
|
||||
if(zone) {
|
||||
std::string zone_script = "quests/";
|
||||
std::string zone_script = Config->QuestDir;
|
||||
zone_script += "/";
|
||||
zone_script += zone->GetShortName();
|
||||
zone_script += "/script_init_v";
|
||||
zone_script += std::to_string(zone->GetInstanceVersion());
|
||||
@@ -870,7 +919,7 @@ void LuaParser::ReloadQuests() {
|
||||
f = fopen(zone_script.c_str(), "r");
|
||||
if(f) {
|
||||
fclose(f);
|
||||
|
||||
|
||||
if(luaL_dofile(L, zone_script.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@@ -879,7 +928,8 @@ void LuaParser::ReloadQuests() {
|
||||
return;
|
||||
}
|
||||
|
||||
zone_script = "quests/";
|
||||
zone_script = Config->QuestDir;
|
||||
zone_script += "/";
|
||||
zone_script += zone->GetShortName();
|
||||
zone_script += "/script_init.lua";
|
||||
f = fopen(zone_script.c_str(), "r");
|
||||
@@ -899,7 +949,7 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) {
|
||||
if(iter != loaded_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(luaL_loadfile(L, filename.c_str())) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@@ -968,6 +1018,7 @@ void LuaParser::MapFunctions(lua_State *L) {
|
||||
lua_register_client_version(),
|
||||
lua_register_appearance(),
|
||||
lua_register_entity(),
|
||||
lua_register_encounter(),
|
||||
lua_register_mob(),
|
||||
lua_register_special_abilities(),
|
||||
lua_register_npc(),
|
||||
@@ -996,7 +1047,7 @@ void LuaParser::MapFunctions(lua_State *L) {
|
||||
lua_register_packet(),
|
||||
lua_register_packet_opcodes()
|
||||
];
|
||||
|
||||
|
||||
} catch(std::exception &ex) {
|
||||
std::string error = ex.what();
|
||||
AddError(error);
|
||||
@@ -1110,7 +1161,7 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite
|
||||
if(iter == lua_encounter_events_registered.end()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
auto riter = iter->second.begin();
|
||||
while(riter != iter->second.end()) {
|
||||
if(riter->event_id == evt) {
|
||||
|
||||
+8
-2
@@ -8,6 +8,10 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "zone_config.h"
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
|
||||
struct lua_State;
|
||||
class ItemInst;
|
||||
class Client;
|
||||
@@ -39,7 +43,7 @@ public:
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
|
||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
||||
@@ -82,7 +86,7 @@ private:
|
||||
uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||
int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
|
||||
void LoadScript(std::string filename, std::string package_name);
|
||||
@@ -99,6 +103,8 @@ private:
|
||||
PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID];
|
||||
ItemArgumentHandler ItemArgumentDispatch[_LargestEventID];
|
||||
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
||||
EncounterArgumentHandler EncounterArgumentDispatch[_LargestEventID];
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "lua_door.h"
|
||||
#include "lua_object.h"
|
||||
#include "lua_packet.h"
|
||||
#include "lua_encounter.h"
|
||||
#include "zone.h"
|
||||
#include "lua_parser_events.h"
|
||||
|
||||
@@ -297,7 +298,7 @@ void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, st
|
||||
|
||||
void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
const Item_Struct *item = database.GetItem(extra_data);
|
||||
const EQEmu::ItemBase *item = database.GetItem(extra_data);
|
||||
if(item) {
|
||||
Lua_Item l_item(item);
|
||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||
@@ -704,4 +705,39 @@ void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* cl
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
}
|
||||
|
||||
void handle_encounter_timer(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
lua_pushstring(L, data.c_str());
|
||||
lua_setfield(L, -2, "timer");
|
||||
}
|
||||
|
||||
void handle_encounter_load(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
if (encounter) {
|
||||
Lua_Encounter l_enc(encounter);
|
||||
luabind::adl::object l_enc_o = luabind::adl::object(L, l_enc);
|
||||
l_enc_o.push(L);
|
||||
lua_setfield(L, -2, "encounter");
|
||||
}
|
||||
if (extra_pointers) {
|
||||
std::string *str = EQEmu::any_cast<std::string*>(extra_pointers->at(0));
|
||||
lua_pushstring(L, str->c_str());
|
||||
lua_setfield(L, -2, "data");
|
||||
}
|
||||
}
|
||||
|
||||
void handle_encounter_unload(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
if (extra_pointers) {
|
||||
std::string *str = EQEmu::any_cast<std::string*>(extra_pointers->at(0));
|
||||
lua_pushstring(L, str->c_str());
|
||||
lua_setfield(L, -2, "data");
|
||||
}
|
||||
}
|
||||
|
||||
void handle_encounter_null(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers) {
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,7 @@ typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::
|
||||
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector<EQEmu::Any>*);
|
||||
typedef void(*EncounterArgumentHandler)(QuestInterface*, lua_State*, Encounter* encounter, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||
|
||||
//NPC
|
||||
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||
@@ -127,5 +128,16 @@ void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Cl
|
||||
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
|
||||
|
||||
//Encounter
|
||||
void handle_encounter_timer(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
void handle_encounter_load(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
void handle_encounter_unload(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
void handle_encounter_null(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||
std::vector<EQEmu::Any> *extra_pointers);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -406,7 +406,7 @@ int Lua_Spell::GetSpellGroup() {
|
||||
|
||||
int Lua_Spell::GetPowerfulFlag() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->powerful_flag;
|
||||
return self->no_resist;
|
||||
}
|
||||
|
||||
int Lua_Spell::GetCastRestriction() {
|
||||
@@ -436,7 +436,7 @@ int Lua_Spell::GetAEMaxTargets() {
|
||||
|
||||
int Lua_Spell::GetMaxTargets() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->maxtargets;
|
||||
return self->no_heal_damage_item_mod;
|
||||
}
|
||||
|
||||
bool Lua_Spell::GetPersistDeath() {
|
||||
|
||||
+350
-81
@@ -12,6 +12,48 @@
|
||||
#include <vector>
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
uint32 EstimateDeflateBuffer(uint32_t len) {
|
||||
z_stream zstream;
|
||||
memset(&zstream, 0, sizeof(zstream));
|
||||
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.opaque = Z_NULL;
|
||||
if (deflateInit(&zstream, Z_FINISH) != Z_OK)
|
||||
return 0;
|
||||
|
||||
return deflateBound(&zstream, len);
|
||||
}
|
||||
|
||||
uint32_t DeflateData(const char *buffer, uint32_t len, char *out_buffer, uint32_t out_len_max) {
|
||||
z_stream zstream;
|
||||
memset(&zstream, 0, sizeof(zstream));
|
||||
int zerror;
|
||||
|
||||
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
|
||||
zstream.avail_in = len;
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.opaque = Z_NULL;
|
||||
deflateInit(&zstream, Z_FINISH);
|
||||
|
||||
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);
|
||||
zstream.avail_out = out_len_max;
|
||||
zerror = deflate(&zstream, Z_FINISH);
|
||||
|
||||
if (zerror == Z_STREAM_END)
|
||||
{
|
||||
deflateEnd(&zstream);
|
||||
return (uint32_t)zstream.total_out;
|
||||
}
|
||||
else
|
||||
{
|
||||
zerror = deflateEnd(&zstream);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) {
|
||||
z_stream zstream;
|
||||
int zerror = 0;
|
||||
@@ -64,7 +106,7 @@ Map::~Map() {
|
||||
|
||||
float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
|
||||
if (!imp)
|
||||
return false;
|
||||
return BEST_Z_INVALID;
|
||||
|
||||
glm::vec3 tmp;
|
||||
if(!result)
|
||||
@@ -93,6 +135,41 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
|
||||
return BEST_Z_INVALID;
|
||||
}
|
||||
|
||||
float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) const {
|
||||
// Unlike FindBestZ, this method finds the closest Z value above or below the specified point.
|
||||
//
|
||||
if (!imp)
|
||||
return false;
|
||||
|
||||
float ClosestZ = BEST_Z_INVALID;
|
||||
|
||||
glm::vec3 tmp;
|
||||
if (!result)
|
||||
result = &tmp;
|
||||
|
||||
glm::vec3 from(start.x, start.y, start.z);
|
||||
glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
|
||||
float hit_distance;
|
||||
bool hit = false;
|
||||
|
||||
// first check is below us
|
||||
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
|
||||
if (hit) {
|
||||
ClosestZ = result->z;
|
||||
|
||||
}
|
||||
|
||||
// Find nearest Z above us
|
||||
to.z = -BEST_Z_INVALID;
|
||||
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
|
||||
if (hit) {
|
||||
if (std::abs(from.z - result->z) < std::abs(ClosestZ - from.z))
|
||||
return result->z;
|
||||
}
|
||||
|
||||
return ClosestZ;
|
||||
}
|
||||
|
||||
bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const {
|
||||
if(!imp)
|
||||
return false;
|
||||
@@ -192,13 +269,12 @@ bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const {
|
||||
}
|
||||
|
||||
Map *Map::LoadMapFile(std::string file) {
|
||||
std::string filename = MAP_DIR;
|
||||
filename += "/";
|
||||
std::string filename = Config->MapDir;
|
||||
std::transform(file.begin(), file.end(), file.begin(), ::tolower);
|
||||
filename += file;
|
||||
filename += ".map";
|
||||
|
||||
Map *m = new Map();
|
||||
auto m = new Map();
|
||||
if (m->Load(filename)) {
|
||||
return m;
|
||||
}
|
||||
@@ -207,7 +283,18 @@ Map *Map::LoadMapFile(std::string file) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Map::Load(std::string filename) {
|
||||
#ifdef USE_MAP_MMFS
|
||||
bool Map::Load(std::string filename, bool force_mmf_overwrite)
|
||||
{
|
||||
if (LoadMMF(filename, force_mmf_overwrite)) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Zone map mmf found - using it in lieu of '%s'", filename.c_str());
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool Map::Load(std::string filename)
|
||||
{
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
FILE *f = fopen(filename.c_str(), "rb");
|
||||
if(f) {
|
||||
uint32 version;
|
||||
@@ -219,10 +306,22 @@ bool Map::Load(std::string filename) {
|
||||
if(version == 0x01000000) {
|
||||
bool v = LoadV1(f);
|
||||
fclose(f);
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
if (v)
|
||||
return SaveMMF(filename, force_mmf_overwrite);
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
return v;
|
||||
} else if(version == 0x02000000) {
|
||||
bool v = LoadV2(f);
|
||||
fclose(f);
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
if (v)
|
||||
return SaveMMF(filename, force_mmf_overwrite);
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
return v;
|
||||
} else {
|
||||
fclose(f);
|
||||
@@ -377,7 +476,9 @@ bool Map::LoadV2(FILE *f) {
|
||||
buf += sizeof(float);
|
||||
|
||||
std::vector<glm::vec3> verts;
|
||||
verts.reserve(vert_count);
|
||||
std::vector<uint32> indices;
|
||||
indices.reserve(ind_count);
|
||||
|
||||
for (uint32 i = 0; i < vert_count; ++i) {
|
||||
float x;
|
||||
@@ -393,16 +494,12 @@ bool Map::LoadV2(FILE *f) {
|
||||
z = *(float*)buf;
|
||||
buf += sizeof(float);
|
||||
|
||||
glm::vec3 vert(x, y, z);
|
||||
verts.push_back(vert);
|
||||
verts.emplace_back(x, y, z);
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < ind_count; ++i) {
|
||||
uint32 index;
|
||||
index = *(uint32*)buf;
|
||||
indices.emplace_back(*(uint32 *)buf);
|
||||
buf += sizeof(uint32);
|
||||
|
||||
indices.push_back(index);
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < nc_vert_count; ++i) {
|
||||
@@ -425,7 +522,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
uint32 poly_count = *(uint32*)buf;
|
||||
buf += sizeof(uint32);
|
||||
|
||||
me->verts.resize(vert_count);
|
||||
me->verts.reserve(vert_count);
|
||||
for (uint32 j = 0; j < vert_count; ++j) {
|
||||
float x = *(float*)buf;
|
||||
buf += sizeof(float);
|
||||
@@ -434,10 +531,10 @@ bool Map::LoadV2(FILE *f) {
|
||||
float z = *(float*)buf;
|
||||
buf += sizeof(float);
|
||||
|
||||
me->verts[j] = glm::vec3(x, y, z);
|
||||
me->verts.emplace_back(x, y, z);
|
||||
}
|
||||
|
||||
me->polys.resize(poly_count);
|
||||
me->polys.reserve(poly_count);
|
||||
for (uint32 j = 0; j < poly_count; ++j) {
|
||||
uint32 v1 = *(uint32*)buf;
|
||||
buf += sizeof(uint32);
|
||||
@@ -453,7 +550,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
p.v2 = v2;
|
||||
p.v3 = v3;
|
||||
p.vis = vis;
|
||||
me->polys[j] = p;
|
||||
me->polys.push_back(p);
|
||||
}
|
||||
|
||||
models[name] = std::move(me);
|
||||
@@ -492,6 +589,8 @@ bool Map::LoadV2(FILE *f) {
|
||||
auto &mod_verts = model->verts;
|
||||
for (uint32 j = 0; j < mod_polys.size(); ++j) {
|
||||
auto ¤t_poly = mod_polys[j];
|
||||
if (current_poly.vis == 0)
|
||||
continue;
|
||||
auto v1 = mod_verts[current_poly.v1];
|
||||
auto v2 = mod_verts[current_poly.v2];
|
||||
auto v3 = mod_verts[current_poly.v3];
|
||||
@@ -508,27 +607,13 @@ bool Map::LoadV2(FILE *f) {
|
||||
TranslateVertex(v2, x, y, z);
|
||||
TranslateVertex(v3, x, y, z);
|
||||
|
||||
float t = v1.x;
|
||||
v1.x = v1.y;
|
||||
v1.y = t;
|
||||
verts.emplace_back(v1.y, v1.x, v1.z); // x/y swapped
|
||||
verts.emplace_back(v2.y, v2.x, v2.z);
|
||||
verts.emplace_back(v3.y, v3.x, v3.z);
|
||||
|
||||
t = v2.x;
|
||||
v2.x = v2.y;
|
||||
v2.y = t;
|
||||
|
||||
t = v3.x;
|
||||
v3.x = v3.y;
|
||||
v3.y = t;
|
||||
|
||||
if (current_poly.vis != 0) {
|
||||
verts.push_back(v1);
|
||||
verts.push_back(v2);
|
||||
verts.push_back(v3);
|
||||
|
||||
indices.push_back((uint32)verts.size() - 3);
|
||||
indices.push_back((uint32)verts.size() - 2);
|
||||
indices.push_back((uint32)verts.size() - 1);
|
||||
}
|
||||
indices.emplace_back((uint32)verts.size() - 3);
|
||||
indices.emplace_back((uint32)verts.size() - 2);
|
||||
indices.emplace_back((uint32)verts.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,6 +681,8 @@ bool Map::LoadV2(FILE *f) {
|
||||
|
||||
for (size_t k = 0; k < model->polys.size(); ++k) {
|
||||
auto &poly = model->polys[k];
|
||||
if (poly.vis == 0)
|
||||
continue;
|
||||
glm::vec3 v1, v2, v3;
|
||||
|
||||
v1 = model->verts[poly.v1];
|
||||
@@ -658,27 +745,13 @@ bool Map::LoadV2(FILE *f) {
|
||||
TranslateVertex(v2, x, y, z);
|
||||
TranslateVertex(v3, x, y, z);
|
||||
|
||||
float t = v1.x;
|
||||
v1.x = v1.y;
|
||||
v1.y = t;
|
||||
verts.emplace_back(v1.y, v1.x, v1.z); // x/y swapped
|
||||
verts.emplace_back(v2.y, v2.x, v2.z);
|
||||
verts.emplace_back(v3.y, v3.x, v3.z);
|
||||
|
||||
t = v2.x;
|
||||
v2.x = v2.y;
|
||||
v2.y = t;
|
||||
|
||||
t = v3.x;
|
||||
v3.x = v3.y;
|
||||
v3.y = t;
|
||||
|
||||
if (poly.vis != 0) {
|
||||
verts.push_back(v1);
|
||||
verts.push_back(v2);
|
||||
verts.push_back(v3);
|
||||
|
||||
indices.push_back((uint32)verts.size() - 3);
|
||||
indices.push_back((uint32)verts.size() - 2);
|
||||
indices.push_back((uint32)verts.size() - 1);
|
||||
}
|
||||
indices.emplace_back((uint32)verts.size() - 3);
|
||||
indices.emplace_back((uint32)verts.size() - 2);
|
||||
indices.emplace_back((uint32)verts.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -724,18 +797,18 @@ bool Map::LoadV2(FILE *f) {
|
||||
float QuadVertex4Z = QuadVertex1Z;
|
||||
|
||||
uint32 current_vert = (uint32)verts.size() + 3;
|
||||
verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
|
||||
verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
|
||||
verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
|
||||
verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
|
||||
verts.emplace_back(QuadVertex1X, QuadVertex1Y, QuadVertex1Z);
|
||||
verts.emplace_back(QuadVertex2X, QuadVertex2Y, QuadVertex2Z);
|
||||
verts.emplace_back(QuadVertex3X, QuadVertex3Y, QuadVertex3Z);
|
||||
verts.emplace_back(QuadVertex4X, QuadVertex4Y, QuadVertex4Z);
|
||||
|
||||
indices.push_back(current_vert);
|
||||
indices.push_back(current_vert - 2);
|
||||
indices.push_back(current_vert - 1);
|
||||
indices.emplace_back(current_vert);
|
||||
indices.emplace_back(current_vert - 2);
|
||||
indices.emplace_back(current_vert - 1);
|
||||
|
||||
indices.push_back(current_vert);
|
||||
indices.push_back(current_vert - 3);
|
||||
indices.push_back(current_vert - 2);
|
||||
indices.emplace_back(current_vert);
|
||||
indices.emplace_back(current_vert - 3);
|
||||
indices.emplace_back(current_vert - 2);
|
||||
}
|
||||
else {
|
||||
//read flags
|
||||
@@ -790,7 +863,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i1 = (uint32)verts.size();
|
||||
verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
|
||||
verts.emplace_back(QuadVertex1X, QuadVertex1Y, QuadVertex1Z);
|
||||
cur_verts[std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)] = i1;
|
||||
}
|
||||
|
||||
@@ -801,7 +874,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i2 = (uint32)verts.size();
|
||||
verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
|
||||
verts.emplace_back(QuadVertex2X, QuadVertex2Y, QuadVertex2Z);
|
||||
cur_verts[std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)] = i2;
|
||||
}
|
||||
|
||||
@@ -812,7 +885,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i3 = (uint32)verts.size();
|
||||
verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
|
||||
verts.emplace_back(QuadVertex3X, QuadVertex3Y, QuadVertex3Z);
|
||||
cur_verts[std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)] = i3;
|
||||
}
|
||||
|
||||
@@ -823,17 +896,17 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
else {
|
||||
i4 = (uint32)verts.size();
|
||||
verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
|
||||
verts.emplace_back(QuadVertex4X, QuadVertex4Y, QuadVertex4Z);
|
||||
cur_verts[std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)] = i4;
|
||||
}
|
||||
|
||||
indices.push_back(i4);
|
||||
indices.push_back(i2);
|
||||
indices.push_back(i3);
|
||||
indices.emplace_back(i4);
|
||||
indices.emplace_back(i2);
|
||||
indices.emplace_back(i3);
|
||||
|
||||
indices.push_back(i4);
|
||||
indices.push_back(i1);
|
||||
indices.push_back(i2);
|
||||
indices.emplace_back(i4);
|
||||
indices.emplace_back(i1);
|
||||
indices.emplace_back(i2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -862,18 +935,18 @@ bool Map::LoadV2(FILE *f) {
|
||||
void Map::RotateVertex(glm::vec3 &v, float rx, float ry, float rz) {
|
||||
glm::vec3 nv = v;
|
||||
|
||||
nv.y = (cos(rx) * v.y) - (sin(rx) * v.z);
|
||||
nv.z = (sin(rx) * v.y) + (cos(rx) * v.z);
|
||||
nv.y = (std::cos(rx) * v.y) - (std::sin(rx) * v.z);
|
||||
nv.z = (std::sin(rx) * v.y) + (std::cos(rx) * v.z);
|
||||
|
||||
v = nv;
|
||||
|
||||
nv.x = (cos(ry) * v.x) + (sin(ry) * v.z);
|
||||
nv.z = -(sin(ry) * v.x) + (cos(ry) * v.z);
|
||||
nv.x = (std::cos(ry) * v.x) + (std::sin(ry) * v.z);
|
||||
nv.z = -(std::sin(ry) * v.x) + (std::cos(ry) * v.z);
|
||||
|
||||
v = nv;
|
||||
|
||||
nv.x = (cos(rz) * v.x) - (sin(rz) * v.y);
|
||||
nv.y = (sin(rz) * v.x) + (cos(rz) * v.y);
|
||||
nv.x = (std::cos(rz) * v.x) - (std::sin(rz) * v.y);
|
||||
nv.y = (std::sin(rz) * v.x) + (std::cos(rz) * v.y);
|
||||
|
||||
v = nv;
|
||||
}
|
||||
@@ -889,3 +962,199 @@ void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
|
||||
v.y = v.y + ty;
|
||||
v.z = v.z + tz;
|
||||
}
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
inline void strip_map_extension(std::string& map_file_name)
|
||||
{
|
||||
auto ext_off = map_file_name.find(".map");
|
||||
if (ext_off != std::string::npos)
|
||||
map_file_name.erase(ext_off, strlen(".map"));
|
||||
}
|
||||
|
||||
inline bool add_mmf_extension(std::string& mmf_file_name)
|
||||
{
|
||||
if (mmf_file_name.empty())
|
||||
return false;
|
||||
|
||||
mmf_file_name.append(".mmf");
|
||||
size_t dot_check = std::count(mmf_file_name.begin(), mmf_file_name.end(), '.');
|
||||
|
||||
return (dot_check == 1);
|
||||
}
|
||||
|
||||
bool Map::LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite)
|
||||
{
|
||||
if (force_mmf_overwrite)
|
||||
return false;
|
||||
|
||||
std::string mmf_file_name = map_file_name;
|
||||
strip_map_extension(mmf_file_name);
|
||||
if (!add_mmf_extension(mmf_file_name)) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s'", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *f = fopen(mmf_file_name.c_str(), "rb");
|
||||
if (!f) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - could not open file", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 file_version;
|
||||
if (fread(&file_version, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@file_version", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 rm_buffer_size;
|
||||
if (fread(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@rm_buffer_size", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 rm_buffer_crc32;
|
||||
if (fread(&rm_buffer_crc32, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@rm_buffer_crc32", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
if (rm_buffer_crc32 != /*crc32_check*/ 0) {
|
||||
fclose(f);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - bad rm_buffer checksum", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 mmf_buffer_size;
|
||||
if (fread(&mmf_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@mmf_buffer_size", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<char> mmf_buffer(mmf_buffer_size);
|
||||
if (fread(mmf_buffer.data(), mmf_buffer_size, 1, f) != 1) {
|
||||
fclose(f);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@mmf_buffer", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
std::vector<char> rm_buffer(rm_buffer_size);
|
||||
uint32 v = InflateData(mmf_buffer.data(), mmf_buffer_size, rm_buffer.data(), rm_buffer_size);
|
||||
|
||||
if (imp) {
|
||||
imp->rm->release();
|
||||
imp->rm = nullptr;
|
||||
}
|
||||
else {
|
||||
imp = new impl;
|
||||
}
|
||||
|
||||
bool load_success = false;
|
||||
imp->rm = loadRaycastMesh(rm_buffer, load_success);
|
||||
if (imp->rm && !load_success) {
|
||||
imp->rm->release();
|
||||
imp->rm = nullptr;
|
||||
}
|
||||
|
||||
if (!imp->rm) {
|
||||
delete imp;
|
||||
imp = nullptr;
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - null RaycastMesh", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
|
||||
{
|
||||
if (!imp || !imp->rm) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file - No implementation (map_file_name: '%s')", map_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string mmf_file_name = map_file_name;
|
||||
strip_map_extension(mmf_file_name);
|
||||
if (!add_mmf_extension(mmf_file_name)) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s'", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* f = fopen(mmf_file_name.c_str(), "rb");
|
||||
if (f) {
|
||||
fclose(f);
|
||||
if (!force_mmf_overwrite)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<char> rm_buffer; // size set in MyRaycastMesh::serialize()
|
||||
serializeRaycastMesh(imp->rm, rm_buffer);
|
||||
if (rm_buffer.empty()) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - empty RaycastMesh buffer", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 rm_buffer_size = rm_buffer.size();
|
||||
uint32 mmf_buffer_size = EstimateDeflateBuffer(rm_buffer.size());
|
||||
|
||||
std::vector<char> mmf_buffer(mmf_buffer_size);
|
||||
|
||||
mmf_buffer_size = DeflateData(rm_buffer.data(), rm_buffer.size(), mmf_buffer.data(), mmf_buffer.size());
|
||||
if (!mmf_buffer_size) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - null MMF buffer size", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
f = fopen(mmf_file_name.c_str(), "wb");
|
||||
if (!f) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - could not open file", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 file_version = 0;
|
||||
if (fwrite(&file_version, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
std::remove(mmf_file_name.c_str());
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@file_version", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
std::remove(mmf_file_name.c_str());
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@rm_buffer_size", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 rm_buffer_crc32 = 0;
|
||||
if (fwrite(&rm_buffer_crc32, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
std::remove(mmf_file_name.c_str());
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@rm_buffer_crc32", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(&mmf_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||
fclose(f);
|
||||
std::remove(mmf_file_name.c_str());
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@mmf_buffer_size", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(mmf_buffer.data(), mmf_buffer_size, 1, f) != 1) {
|
||||
fclose(f);
|
||||
std::remove(mmf_file_name.c_str());
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@mmf_buffer", mmf_file_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
+16
@@ -25,8 +25,12 @@
|
||||
#include "position.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zone_config.h"
|
||||
|
||||
#define BEST_Z_INVALID -99999
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
@@ -34,10 +38,17 @@ public:
|
||||
~Map();
|
||||
|
||||
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
float FindClosestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
bool Load(std::string filename, bool force_mmf_overwrite = false);
|
||||
#else
|
||||
bool Load(std::string filename);
|
||||
#endif
|
||||
|
||||
static Map *LoadMapFile(std::string file);
|
||||
private:
|
||||
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
||||
@@ -46,6 +57,11 @@ private:
|
||||
bool LoadV1(FILE *f);
|
||||
bool LoadV2(FILE *f);
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
bool LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||
bool SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
struct impl;
|
||||
impl *imp;
|
||||
};
|
||||
|
||||
+177
-150
File diff suppressed because it is too large
Load Diff
+18
-13
@@ -8,11 +8,15 @@ class Corpse;
|
||||
class Group;
|
||||
class Mob;
|
||||
class Raid;
|
||||
struct Item_Struct;
|
||||
struct MercTemplate;
|
||||
struct NPCType;
|
||||
struct NewSpawn_Struct;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemBase;
|
||||
}
|
||||
|
||||
#define MAXMERCS 1
|
||||
#define TANK 1
|
||||
#define HEALER 2
|
||||
@@ -60,10 +64,10 @@ public:
|
||||
virtual ~Merc();
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
@@ -177,10 +181,10 @@ public:
|
||||
inline const uint8 GetClientVersion() const { return _OwnerClientVersion; }
|
||||
|
||||
virtual void SetTarget(Mob* mob);
|
||||
bool HasSkill(SkillUseTypes skill_id) const;
|
||||
bool CanHaveSkill(SkillUseTypes skill_id) const;
|
||||
uint16 MaxSkill(SkillUseTypes skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(SkillUseTypes skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
bool HasSkill(EQEmu::skills::SkillType skill_id) const;
|
||||
bool CanHaveSkill(EQEmu::skills::SkillType skill_id) const;
|
||||
uint16 MaxSkill(EQEmu::skills::SkillType skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(EQEmu::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
virtual void DoClassAttacks(Mob *target);
|
||||
void CheckHateList();
|
||||
bool CheckTaunt();
|
||||
@@ -192,6 +196,7 @@ public:
|
||||
virtual void ScaleStats(int scalepercent, bool setmax = false);
|
||||
virtual void CalcBonuses();
|
||||
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
|
||||
inline uint8 GetEndurancePercent() { return (uint8)((float)cur_end / (float)max_end * 100.0f); }
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
inline virtual int32 GetATK() const { return ATK; }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
@@ -278,7 +283,7 @@ public:
|
||||
|
||||
protected:
|
||||
void CalcItemBonuses(StatBonuses* newbon);
|
||||
void AddItemBonuses(const Item_Struct *item, StatBonuses* newbon);
|
||||
void AddItemBonuses(const EQEmu::ItemBase *item, StatBonuses* newbon);
|
||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
@@ -286,8 +291,8 @@ protected:
|
||||
std::vector<MercSpell> merc_spells;
|
||||
std::map<uint32,MercTimer> timers;
|
||||
|
||||
uint16 skills[HIGHEST_SKILL+1];
|
||||
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
|
||||
uint16 skills[EQEmu::skills::HIGHEST_SKILL + 1];
|
||||
uint32 equipment[EQEmu::legacy::EQUIPMENT_SIZE]; //this is an array of item IDs
|
||||
uint16 d_melee_texture1; //this is an item Material value
|
||||
uint16 d_melee_texture2; //this is an item Material value (offhand)
|
||||
uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation
|
||||
@@ -397,4 +402,4 @@ private:
|
||||
Timer check_target_timer;
|
||||
};
|
||||
|
||||
#endif // MERC_H
|
||||
#endif // MERC_H
|
||||
|
||||
+1051
-480
File diff suppressed because it is too large
Load Diff
+244
-108
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
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
|
||||
@@ -23,10 +23,18 @@
|
||||
#include "hate_list.h"
|
||||
#include "pathing.h"
|
||||
#include "position.h"
|
||||
#include "aa_ability.h"
|
||||
#include "aa.h"
|
||||
#include "../common/light_source.h"
|
||||
#include "../common/emu_constants.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#ifdef BOTS
|
||||
#include "heal_rotation.h"
|
||||
#endif
|
||||
|
||||
char* strn0cpy(char* dest, const char* source, uint32 size);
|
||||
|
||||
#define MAX_SPECIAL_ATTACK_PARAMS 8
|
||||
@@ -38,10 +46,14 @@ class Group;
|
||||
class ItemInst;
|
||||
class NPC;
|
||||
class Raid;
|
||||
struct Item_Struct;
|
||||
struct NewSpawn_Struct;
|
||||
struct PlayerPositionUpdateServer_Struct;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemBase;
|
||||
}
|
||||
|
||||
class Mob : public Entity {
|
||||
public:
|
||||
enum CLIENT_CONN_STATUS { CLIENT_CONNECTING, CLIENT_CONNECTED, CLIENT_LINKDEAD,
|
||||
@@ -102,7 +114,7 @@ public:
|
||||
uint32 in_drakkin_heritage,
|
||||
uint32 in_drakkin_tattoo,
|
||||
uint32 in_drakkin_details,
|
||||
uint32 in_armor_tint[_MaterialCount],
|
||||
EQEmu::TintProfile in_armor_tint,
|
||||
uint8 in_aa_title,
|
||||
uint8 in_see_invis, // see through invis
|
||||
uint8 in_see_invis_undead, // see through invis vs. undead
|
||||
@@ -112,7 +124,12 @@ public:
|
||||
int32 in_mana_regen,
|
||||
uint8 in_qglobal,
|
||||
uint8 in_maxlevel,
|
||||
uint32 in_scalerate
|
||||
uint32 in_scalerate,
|
||||
uint8 in_armtexture,
|
||||
uint8 in_bracertexture,
|
||||
uint8 in_handtexture,
|
||||
uint8 in_legtexture,
|
||||
uint8 in_feettexture
|
||||
);
|
||||
virtual ~Mob();
|
||||
|
||||
@@ -137,28 +154,44 @@ public:
|
||||
virtual void ThrowingAttack(Mob* other) { }
|
||||
uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg);
|
||||
// 13 = Primary (default), 14 = secondary
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) = 0;
|
||||
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||
void TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary, int damage = 0);
|
||||
virtual bool AvoidDamage(Mob* attacker, int32 &damage, bool CanRiposte = true);
|
||||
virtual bool CheckHitChance(Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod = 0);
|
||||
bool AvoidDamage(Mob* attacker, int32 &damage, int hand);
|
||||
virtual bool CheckHitChance(Mob* attacker, EQEmu::skills::SkillType skillinuse, int Hand, int16 chance_mod = 0);
|
||||
virtual void TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttackOptions *opts = nullptr);
|
||||
void TryPetCriticalHit(Mob *defender, uint16 skill, int32 &damage);
|
||||
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);
|
||||
uint32 TryHeadShot(Mob* defender, SkillUseTypes skillInUse);
|
||||
uint32 TryAssassinate(Mob* defender, SkillUseTypes skillInUse, uint16 ReuseTime);
|
||||
virtual bool TryFinishingBlow(Mob *defender, EQEmu::skills::SkillType skillinuse);
|
||||
uint32 TryHeadShot(Mob* defender, EQEmu::skills::SkillType skillInUse);
|
||||
uint32 TryAssassinate(Mob* defender, EQEmu::skills::SkillType skillInUse, uint16 ReuseTime);
|
||||
virtual void DoRiposte(Mob* defender);
|
||||
void ApplyMeleeDamageBonus(uint16 skill, int32 &damage);
|
||||
void ApplyMeleeDamageBonus(uint16 skill, int32 &damage,ExtraAttackOptions *opts = nullptr);
|
||||
virtual void MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttackOptions *opts = nullptr);
|
||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
bool CombatRange(Mob* other);
|
||||
virtual inline bool IsBerserk() { return false; } // only clients
|
||||
void RogueEvade(Mob *other);
|
||||
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse);
|
||||
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, EQEmu::skills::SkillType skillInUse, ExtraAttackOptions *opts = nullptr);
|
||||
void BreakInvisibleSpells();
|
||||
virtual void CancelSneakHide();
|
||||
void CommonBreakInvisible();
|
||||
void CommonBreakInvisibleFromCombat();
|
||||
bool HasDied();
|
||||
virtual bool CheckDualWield();
|
||||
void DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
void DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
virtual bool CheckDoubleAttack();
|
||||
// inline process for places where we need to do them outside of the AI_Process
|
||||
void ProcessAttackRounds(Mob *target, ExtraAttackOptions *opts = nullptr, int special = 0)
|
||||
{
|
||||
if (target) {
|
||||
DoMainHandAttackRounds(target, opts, special);
|
||||
if (CanThisClassDualWield())
|
||||
DoOffHandAttackRounds(target, opts, special);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Appearance
|
||||
void SendLevelAppearance();
|
||||
@@ -166,14 +199,15 @@ public:
|
||||
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
|
||||
Client *specific_target=nullptr);
|
||||
void SendTargetable(bool on, Client *specific_target = nullptr);
|
||||
virtual void SendWearChange(uint8 material_slot);
|
||||
virtual void SendArmorAppearance(Client *one_client = nullptr);
|
||||
virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr);
|
||||
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
|
||||
uint32 unknown06 = 0, uint32 unknown18 = 0);
|
||||
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);
|
||||
virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model = 0);
|
||||
void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone);
|
||||
void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0,
|
||||
float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, SkillUseTypes skillInUse = SkillArchery);
|
||||
float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQEmu::skills::SkillType skillInUse = EQEmu::skills::SkillArchery);
|
||||
void ChangeSize(float in_size, bool bNoRestriction = false);
|
||||
inline uint8 SeeInvisible() const { return see_invis; }
|
||||
inline bool SeeInvisibleUndead() const { return see_invis_undead; }
|
||||
@@ -181,11 +215,11 @@ public:
|
||||
inline bool SeeImprovedHide() const { return see_improved_hide; }
|
||||
bool IsInvisible(Mob* other = 0) const;
|
||||
void SetInvisible(uint8 state);
|
||||
bool AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* weapon);
|
||||
bool AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const ItemInst* weapon);
|
||||
|
||||
//Song
|
||||
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
|
||||
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, uint16 slot);
|
||||
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, EQEmu::CastingSlot slot);
|
||||
void BardPulse(uint16 spell_id, Mob *caster);
|
||||
|
||||
//Spell
|
||||
@@ -194,7 +228,7 @@ public:
|
||||
bool IsBeneficialAllowed(Mob *target);
|
||||
virtual int GetCasterLevel(uint16 spell_id);
|
||||
void ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* newbon, uint16 casterID = 0,
|
||||
uint8 WornType = 0, uint32 ticsremaining = 0, int buffslot = -1,
|
||||
uint8 WornType = 0, int32 ticsremaining = 0, int buffslot = -1, int instrument_mod = 10,
|
||||
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
|
||||
void NegateSpellsBonuses(uint16 spell_id);
|
||||
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);
|
||||
@@ -205,34 +239,40 @@ public:
|
||||
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration);
|
||||
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
|
||||
float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false,
|
||||
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false);
|
||||
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false,
|
||||
int level_override = -1);
|
||||
int ResistPhysical(int level_diff, uint8 caster_level);
|
||||
int ResistElementalWeaponDmg(const ItemInst *item);
|
||||
int CheckBaneDamage(const ItemInst *item);
|
||||
uint16 GetSpecializeSkillValue(uint16 spell_id) const;
|
||||
void SendSpellBarDisable();
|
||||
void SendSpellBarEnable(uint16 spellid);
|
||||
void ZeroCastingVars();
|
||||
virtual void SpellProcess();
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1,
|
||||
virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1,
|
||||
int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF,
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 *resist_adjust = nullptr);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = 10, int32 casttime = -1,
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, int16 *resist_adjust = nullptr,
|
||||
uint32 aa_id = 0);
|
||||
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1,
|
||||
int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF,
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 resist_adjust = 0);
|
||||
void CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint16 mana_used,
|
||||
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, int16 resist_adjust = 0,
|
||||
uint32 aa_id = 0);
|
||||
void CastedSpellFinished(uint16 spell_id, uint32 target_id, EQEmu::CastingSlot slot, uint16 mana_used,
|
||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
|
||||
bool SpellFinished(uint16 spell_id, Mob *target, uint16 slot = 10, uint16 mana_used = 0,
|
||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false);
|
||||
bool SpellFinished(uint16 spell_id, Mob *target, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, uint16 mana_used = 0,
|
||||
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1);
|
||||
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect = false,
|
||||
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false);
|
||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
|
||||
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1);
|
||||
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1);
|
||||
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center,
|
||||
CastAction_type &CastAction);
|
||||
CastAction_type &CastAction, EQEmu::CastingSlot slot, bool isproc = false);
|
||||
virtual bool CheckFizzle(uint16 spell_id);
|
||||
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
|
||||
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
|
||||
virtual float GetAOERange(uint16 spell_id);
|
||||
void InterruptSpell(uint16 spellid = SPELL_UNKNOWN);
|
||||
void InterruptSpell(uint16, uint16, uint16 spellid = SPELL_UNKNOWN);
|
||||
void StopCasting();
|
||||
inline bool IsCasting() const { return((casting_spell_id != 0)); }
|
||||
uint16 CastingSpellID() const { return casting_spell_id; }
|
||||
bool DoCastingChecks();
|
||||
@@ -247,7 +287,7 @@ public:
|
||||
|
||||
//Buff
|
||||
void BuffProcess();
|
||||
virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0);
|
||||
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
|
||||
void BuffFadeBySpellID(uint16 spell_id);
|
||||
void BuffFadeByEffect(int effectid, int skipslot = -1);
|
||||
void BuffFadeAll();
|
||||
@@ -268,6 +308,8 @@ public:
|
||||
virtual int GetMaxSongSlots() const { return 0; }
|
||||
virtual int GetMaxDiscSlots() const { return 0; }
|
||||
virtual int GetMaxTotalSlots() const { return 0; }
|
||||
virtual uint32 GetFirstBuffSlot(bool disc, bool song);
|
||||
virtual uint32 GetLastBuffSlot(bool disc, bool song);
|
||||
virtual void InitializeBuffSlots() { buffs = nullptr; current_buff_count = 0; }
|
||||
virtual void UninitializeBuffSlots() { }
|
||||
EQApplicationPacket *MakeBuffsPacket(bool for_target = true);
|
||||
@@ -311,7 +353,9 @@ public:
|
||||
inline void SetShieldEquiped(bool val) { has_shieldequiped = val; }
|
||||
bool HasTwoHandBluntEquiped() const { return has_twohandbluntequiped; }
|
||||
inline void SetTwoHandBluntEquiped(bool val) { has_twohandbluntequiped = val; }
|
||||
virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; }
|
||||
bool HasTwoHanderEquipped() { return has_twohanderequipped; }
|
||||
void SetTwoHanderEquipped(bool val) { has_twohanderequipped = val; }
|
||||
virtual uint16 GetSkill(EQEmu::skills::SkillType skill_num) const { return 0; }
|
||||
virtual uint32 GetEquipment(uint8 material_slot) const { return(0); }
|
||||
virtual int32 GetEquipmentMaterial(uint8 material_slot) const;
|
||||
virtual int32 GetHerosForgeModel(uint8 material_slot) const;
|
||||
@@ -319,9 +363,9 @@ public:
|
||||
virtual uint32 IsEliteMaterialItem(uint8 material_slot) const;
|
||||
bool CanClassEquipItem(uint32 item_id);
|
||||
bool AffectedBySpellExcludingSlot(int slot, int effect);
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) = 0;
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill,
|
||||
bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) = 0;
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) = 0;
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill,
|
||||
bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) = 0;
|
||||
inline virtual void SetHP(int32 hp) { if (hp >= max_hp) cur_hp = max_hp; else cur_hp = hp;}
|
||||
bool ChangeHP(Mob* other, int32 amount, uint16 spell_id = 0, int8 buffslot = -1, bool iBuffTic = false);
|
||||
inline void SetOOCRegen(int32 newoocregen) {oocregen = newoocregen;}
|
||||
@@ -331,6 +375,7 @@ public:
|
||||
virtual inline uint16 GetBaseRace() const { return base_race; }
|
||||
virtual inline uint8 GetBaseGender() const { return base_gender; }
|
||||
virtual inline uint16 GetDeity() const { return deity; }
|
||||
virtual EQEmu::deity::DeityTypeBit GetDeityBit() { return EQEmu::deity::ConvertDeityTypeToDeityTypeBit((EQEmu::deity::DeityType)deity); }
|
||||
inline uint16 GetRace() const { return race; }
|
||||
inline uint8 GetGender() const { return gender; }
|
||||
inline uint8 GetTexture() const { return texture; }
|
||||
@@ -345,7 +390,7 @@ public:
|
||||
inline uint8 GetDrakkinHeritage() const { return drakkin_heritage; }
|
||||
inline uint8 GetDrakkinTattoo() const { return drakkin_tattoo; }
|
||||
inline uint8 GetDrakkinDetails() const { return drakkin_details; }
|
||||
inline uint32 GetArmorTint(uint8 i) const { return armor_tint[(i < _MaterialCount) ? i : 0]; }
|
||||
inline uint32 GetArmorTint(uint8 i) const { return armor_tint.Slot[(i < EQEmu::textures::TextureCount) ? i : 0].Color; }
|
||||
inline uint8 GetClass() const { return class_; }
|
||||
inline uint8 GetLevel() const { return level; }
|
||||
inline uint8 GetOrigLevel() const { return orig_level; }
|
||||
@@ -358,6 +403,7 @@ public:
|
||||
inline Mob* GetTarget() const { return target; }
|
||||
virtual void SetTarget(Mob* mob);
|
||||
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); }
|
||||
virtual inline int GetIntHPRatio() const { return max_hp == 0 ? 0 : static_cast<int>(cur_hp * 100 / max_hp); }
|
||||
inline virtual int32 GetAC() const { return AC + itembonuses.AC + spellbonuses.AC; }
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK; }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
@@ -396,6 +442,8 @@ public:
|
||||
virtual int32 CalcMaxHP();
|
||||
inline int32 GetMaxMana() const { return max_mana; }
|
||||
inline int32 GetMana() const { return cur_mana; }
|
||||
virtual int32 GetEndurance() const { return 0; }
|
||||
virtual void SetEndurance(int32 newEnd) { return; }
|
||||
int32 GetItemHPBonuses();
|
||||
int32 GetSpellHPBonuses();
|
||||
virtual const int32& SetMana(int32 amount);
|
||||
@@ -403,6 +451,7 @@ public:
|
||||
((static_cast<float>(cur_mana) / max_mana) * 100); }
|
||||
virtual int32 CalcMaxMana();
|
||||
uint32 GetNPCTypeID() const { return npctype_id; }
|
||||
void SetNPCTypeID(uint32 npctypeid) { npctype_id = npctypeid; }
|
||||
inline const glm::vec4& GetPosition() const { return m_Position; }
|
||||
inline const float GetX() const { return m_Position.x; }
|
||||
inline const float GetY() const { return m_Position.y; }
|
||||
@@ -434,10 +483,13 @@ public:
|
||||
inline bool IsMoving() const { return moving; }
|
||||
virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); }
|
||||
virtual void GoToBind(uint8 bindnum = 0) { }
|
||||
virtual void Gate();
|
||||
float GetWalkspeed() const { return(_GetMovementSpeed(-47)); }
|
||||
float GetRunspeed() const { return(_GetMovementSpeed(0)); }
|
||||
float GetBaseRunspeed() const { return runspeed; }
|
||||
virtual void Gate(uint8 bindnum = 0);
|
||||
int GetWalkspeed() const { return(_GetWalkSpeed()); }
|
||||
int GetRunspeed() const { return(_GetRunSpeed()); }
|
||||
void SetCurrentSpeed(int in);
|
||||
int GetBaseRunspeed() const { return base_runspeed; }
|
||||
int GetBaseWalkspeed() const { return base_walkspeed; }
|
||||
int GetBaseFearSpeed() const { return base_fearspeed; }
|
||||
float GetMovespeed() const { return IsRunning() ? GetRunspeed() : GetWalkspeed(); }
|
||||
bool IsRunning() const { return m_is_running; }
|
||||
void SetRunning(bool val) { m_is_running = val; }
|
||||
@@ -448,6 +500,8 @@ public:
|
||||
void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu);
|
||||
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);
|
||||
void SendPosition();
|
||||
void SetSpawned() { spawned = true; };
|
||||
bool Spawned() { return spawned; };
|
||||
void SetFlyMode(uint8 flymode);
|
||||
inline void Teleport(glm::vec3 NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y;
|
||||
m_Position.z = NewPosition.z; };
|
||||
@@ -457,7 +511,7 @@ public:
|
||||
inline uint32 GetLevelCon(uint8 iOtherLevel) const {
|
||||
return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; }
|
||||
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true,
|
||||
bool bFrenzy = false, bool iBuffTic = false);
|
||||
bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN);
|
||||
bool RemoveFromHateList(Mob* mob);
|
||||
void SetHateAmountOnEnt(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.SetHateAmountOnEnt(other,hate,damage);}
|
||||
void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate > 1 ? in_hate / 2 : 1)); }
|
||||
@@ -469,6 +523,10 @@ public:
|
||||
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
|
||||
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
|
||||
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
|
||||
bool HasPrimaryAggro() { return PrimaryAggro; }
|
||||
bool HasAssistAggro() { return AssistAggro; }
|
||||
void SetPrimaryAggro(bool value) { PrimaryAggro = value; if (value) AssistAggro = false; }
|
||||
void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; }
|
||||
bool HateSummon();
|
||||
void FaceTarget(Mob* MobToFace = 0);
|
||||
void SetHeading(float iHeading) { if(m_Position.w != iHeading) { pLastChange = Timer::GetCurrentTime();
|
||||
@@ -487,7 +545,6 @@ public:
|
||||
inline bool CheckLastLosState() const { return last_los_check; }
|
||||
|
||||
//Quest
|
||||
void QuestReward(Client *c = nullptr, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0);
|
||||
void CameraEffect(uint32 duration, uint32 intensity, Client *c = nullptr, bool global = false);
|
||||
inline bool GetQglobal() const { return qglobal; }
|
||||
|
||||
@@ -498,14 +555,15 @@ public:
|
||||
static void CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns);
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
void CreateHPPacket(EQApplicationPacket* app);
|
||||
void SendHPUpdate();
|
||||
void SendHPUpdate(bool skip_self = false);
|
||||
virtual void ResetHPUpdateTimer() {}; // does nothing
|
||||
|
||||
//Util
|
||||
static uint32 RandomTimer(int min, int max);
|
||||
static uint8 GetDefaultGender(uint16 in_race, uint8 in_gender = 0xFF);
|
||||
static bool IsPlayerRace(uint16 in_race);
|
||||
uint16 GetSkillByItemType(int ItemType);
|
||||
uint8 GetItemTypeBySkill(SkillUseTypes skill);
|
||||
uint8 GetItemTypeBySkill(EQEmu::skills::SkillType skill);
|
||||
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
|
||||
virtual void MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const char *petname = nullptr, float in_size = 0.0f);
|
||||
bool IsWarriorClass() const;
|
||||
@@ -519,6 +577,7 @@ public:
|
||||
bool lookForAftArc = true);
|
||||
|
||||
//Procs
|
||||
void TriggerDefensiveProcs(Mob *on, uint16 hand = EQEmu::legacy::SlotPrimary, bool FromSkillProc = false, int damage = 0);
|
||||
bool AddRangedProc(uint16 spell_id, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||
bool RemoveRangedProc(uint16 spell_id, bool bAll = false);
|
||||
bool HasRangedProcs() const;
|
||||
@@ -527,7 +586,7 @@ public:
|
||||
bool HasDefensiveProcs() const;
|
||||
bool HasSkillProcs() const;
|
||||
bool HasSkillProcSuccess() const;
|
||||
bool AddProcToWeapon(uint16 spell_id, bool bPerma = false, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN);
|
||||
bool AddProcToWeapon(uint16 spell_id, bool bPerma = false, uint16 iChance = 3, uint16 base_spell_id = SPELL_UNKNOWN, int level_override = -1);
|
||||
bool RemoveProcFromWeapon(uint16 spell_id, bool bAll = false);
|
||||
bool HasProcs() const;
|
||||
bool IsCombatProc(uint16 spell_id);
|
||||
@@ -597,7 +656,7 @@ public:
|
||||
int32 GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining);
|
||||
int32 GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill = false, uint16 skill=0);
|
||||
int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id);
|
||||
int16 GetSkillDmgTaken(const SkillUseTypes skill_used);
|
||||
int16 GetSkillDmgTaken(const EQEmu::skills::SkillType skill_used, ExtraAttackOptions *opts = nullptr);
|
||||
void DoKnockback(Mob *caster, uint32 pushback, uint32 pushup);
|
||||
int16 CalcResistChanceBonus();
|
||||
int16 CalcFearResistChance();
|
||||
@@ -617,7 +676,7 @@ public:
|
||||
bool TryReflectSpell(uint32 spell_id);
|
||||
bool CanBlockSpell() const { return(spellbonuses.BlockNextSpell); }
|
||||
bool DoHPToManaCovert(uint16 mana_cost = 0);
|
||||
int32 ApplySpellEffectiveness(Mob* caster, int16 spell_id, int32 value, bool IsBard = false);
|
||||
int32 ApplySpellEffectiveness(int16 spell_id, int32 value, bool IsBard = false, uint16 caster_id=0);
|
||||
int8 GetDecayEffectValue(uint16 spell_id, uint16 spelleffect);
|
||||
int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg);
|
||||
void MeleeLifeTap(int32 damage);
|
||||
@@ -630,8 +689,8 @@ public:
|
||||
inline void SetSpellPowerDistanceMod(int16 value) { SpellPowerDistanceMod = value; };
|
||||
int32 GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot = 0);
|
||||
|
||||
void ModSkillDmgTaken(SkillUseTypes skill_num, int value);
|
||||
int16 GetModSkillDmgTaken(const SkillUseTypes skill_num);
|
||||
void ModSkillDmgTaken(EQEmu::skills::SkillType skill_num, int value);
|
||||
int16 GetModSkillDmgTaken(const EQEmu::skills::SkillType skill_num);
|
||||
void ModVulnerability(uint8 resist, int16 value);
|
||||
int16 GetModVulnerability(const uint8 resist);
|
||||
|
||||
@@ -655,17 +714,17 @@ public:
|
||||
bool IsDestructibleObject() { return destructibleobject; }
|
||||
void SetDestructibleObject(bool in) { destructibleobject = in; }
|
||||
|
||||
inline uint8 GetInnateLightType() { return m_Light.Type.Innate; }
|
||||
inline uint8 GetEquipmentLightType() { return m_Light.Type.Equipment; }
|
||||
inline uint8 GetSpellLightType() { return m_Light.Type.Spell; }
|
||||
inline uint8 GetInnateLightType() { return m_Light.Type[EQEmu::lightsource::LightInnate]; }
|
||||
inline uint8 GetEquipmentLightType() { return m_Light.Type[EQEmu::lightsource::LightEquipment]; }
|
||||
inline uint8 GetSpellLightType() { return m_Light.Type[EQEmu::lightsource::LightSpell]; }
|
||||
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type.Equipment = 0; m_Light.Level.Equipment = 0; }
|
||||
inline void SetSpellLightType(uint8 lightType) { m_Light.Type.Spell = (lightType & 0x0F); m_Light.Level.Spell = m_Light.TypeToLevel(m_Light.Type.Spell); }
|
||||
virtual void UpdateEquipmentLight() { m_Light.Type[EQEmu::lightsource::LightEquipment] = 0; m_Light.Level[EQEmu::lightsource::LightEquipment] = 0; }
|
||||
inline void SetSpellLightType(uint8 light_type) { m_Light.Type[EQEmu::lightsource::LightSpell] = (light_type & 0x0F); m_Light.Level[EQEmu::lightsource::LightSpell] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightSpell]); }
|
||||
|
||||
inline uint8 GetActiveLightType() { return m_Light.Type.Active; }
|
||||
inline uint8 GetActiveLightType() { return m_Light.Type[EQEmu::lightsource::LightActive]; }
|
||||
bool UpdateActiveLight(); // returns true if change, false if no change
|
||||
|
||||
LightProfile_Struct* GetLightProfile() { return &m_Light; }
|
||||
EQEmu::LightSourceProfile* GetLightProfile() { return &m_Light; }
|
||||
|
||||
Mob* GetPet();
|
||||
void SetPet(Mob* newpet);
|
||||
@@ -713,19 +772,21 @@ public:
|
||||
inline bool GetInvul(void) { return invulnerable; }
|
||||
inline void SetExtraHaste(int Haste) { ExtraHaste = Haste; }
|
||||
virtual int GetHaste();
|
||||
int32 GetMeleeMitigation();
|
||||
|
||||
uint8 GetWeaponDamageBonus(const Item_Struct* Weapon);
|
||||
uint16 GetDamageTable(SkillUseTypes skillinuse);
|
||||
virtual int GetMonkHandToHandDamage(void);
|
||||
uint8 GetWeaponDamageBonus(const EQEmu::ItemBase* weapon, bool offhand = false);
|
||||
uint16 GetDamageTable(EQEmu::skills::SkillType skillinuse);
|
||||
virtual int GetHandToHandDamage(void);
|
||||
|
||||
bool CanThisClassDoubleAttack(void) const;
|
||||
bool CanThisClassTripleAttack() const;
|
||||
bool CanThisClassDualWield(void) const;
|
||||
bool CanThisClassRiposte(void) const;
|
||||
bool CanThisClassDodge(void) const;
|
||||
bool CanThisClassParry(void) const;
|
||||
bool CanThisClassBlock(void) const;
|
||||
|
||||
int GetMonkHandToHandDelay(void);
|
||||
int GetHandToHandDelay(void);
|
||||
uint32 GetClassLevelFactor();
|
||||
void Mesmerize();
|
||||
inline bool IsMezzed() const { return mezzed; }
|
||||
@@ -737,11 +798,11 @@ public:
|
||||
int32 AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTic, Mob* attacker);
|
||||
int32 ReduceAllDamage(int32 damage);
|
||||
|
||||
virtual void DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance=false, bool CanAvoid=true);
|
||||
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* AmmoItem=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 range_id=0, int AmmoSlot=0, float speed = 4.0f);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime=0);
|
||||
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0, uint32 range_id=0, uint32 ammo_id=0, const Item_Struct *AmmoItem=nullptr, int AmmoSlot=0, float speed= 4.0f);
|
||||
bool TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed);
|
||||
virtual void DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool CheckHitChance = false, bool CanAvoid = true);
|
||||
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon = nullptr, const EQEmu::ItemBase* AmmoItem = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, int AmmoSlot = 0, float speed = 4.0f);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
|
||||
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon = nullptr, const ItemInst* Ammo = nullptr, uint16 weapon_damage = 0, int16 chance_mod = 0, int16 focus = 0, int ReuseTime = 0, uint32 range_id = 0, uint32 ammo_id = 0, const EQEmu::ItemBase *AmmoItem = nullptr, int AmmoSlot = 0, float speed = 4.0f);
|
||||
bool TryProjectileAttack(Mob* other, const EQEmu::ItemBase *item, EQEmu::skills::SkillType skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed);
|
||||
void ProjectileAttack();
|
||||
inline bool HasProjectileAttack() const { return ActiveProjectileATK; }
|
||||
inline void SetProjectileAttack(bool value) { ActiveProjectileATK = value; }
|
||||
@@ -756,7 +817,7 @@ public:
|
||||
void StartEnrage();
|
||||
void ProcessEnrage();
|
||||
bool IsEnraged();
|
||||
void Taunt(NPC* who, bool always_succeed, float chance_bonus = 0);
|
||||
void Taunt(NPC* who, bool always_succeed, float chance_bonus=0, bool FromSpell=false, int32 bonus_hate=0);
|
||||
|
||||
virtual void AI_Init();
|
||||
virtual void AI_Start(uint32 iMoveDelay = 0);
|
||||
@@ -796,9 +857,8 @@ public:
|
||||
|
||||
//old fear function
|
||||
//void SetFeared(Mob *caster, uint32 duration, bool flee = false);
|
||||
float GetFearSpeed();
|
||||
bool IsFeared() { return curfp; } // This returns true if the mob is feared or fleeing due to low HP
|
||||
//old fear: inline void StartFleeing() { SetFeared(GetHateTop(), FLEE_RUN_DURATION, true); }
|
||||
int GetFearSpeed() { return _GetFearSpeed(); }
|
||||
bool IsFeared() { return (spellbonuses.IsFeared || flee_mode); } // This returns true if the mob is feared or fleeing due to low HP
|
||||
inline void StartFleeing() { flee_mode = true; CalculateNewFearpoint(); }
|
||||
void ProcessFlee();
|
||||
void CheckFlee();
|
||||
@@ -806,8 +866,8 @@ public:
|
||||
|
||||
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
|
||||
float CalculateHeadingToTarget(float in_x, float in_y);
|
||||
bool CalculateNewPosition(float x, float y, float z, float speed, bool checkZ = false);
|
||||
virtual bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true);
|
||||
bool CalculateNewPosition(float x, float y, float z, int speed, bool checkZ = false, bool calcheading = true);
|
||||
virtual bool CalculateNewPosition2(float x, float y, float z, int speed, bool checkZ = true, bool calcheading = true);
|
||||
float CalculateDistance(float x, float y, float z);
|
||||
float GetGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
void SendTo(float new_x, float new_y, float new_z);
|
||||
@@ -845,15 +905,14 @@ public:
|
||||
Mob* GetShieldTarget() const { return shield_target; }
|
||||
void SetShieldTarget(Mob* mob) { shield_target = mob; }
|
||||
bool HasActiveSong() const { return(bardsong != 0); }
|
||||
bool Charmed() const { return charmed; }
|
||||
bool Charmed() const { return typeofpet == petCharmed; }
|
||||
static uint32 GetLevelHP(uint8 tlevel);
|
||||
uint32 GetZoneID() const; //for perl
|
||||
virtual int32 CheckAggroAmount(uint16 spell_id, bool isproc = false);
|
||||
virtual int32 CheckHealAggroAmount(uint16 spell_id, uint32 heal_possible = 0);
|
||||
virtual uint32 GetAA(uint32 aa_id) const { return(0); }
|
||||
virtual int32 CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc = false);
|
||||
virtual int32 CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possible = 0);
|
||||
|
||||
uint32 GetInstrumentMod(uint16 spell_id) const;
|
||||
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, Mob *caster = nullptr, int ticsremaining = 0);
|
||||
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, uint32 instrument_mod = 10, Mob *caster = nullptr, int ticsremaining = 0,uint16 casterid=0);
|
||||
int CalcSpellEffectValue_formula(int formula, int base, int max, int caster_level, uint16 spell_id, int ticsremaining = 0);
|
||||
virtual int CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1 = nullptr, Mob* caster2 = nullptr, int buffslot = -1);
|
||||
uint32 GetCastedSpellInvSlot() const { return casting_spell_inventory_slot; }
|
||||
@@ -861,7 +920,7 @@ public:
|
||||
// HP Event
|
||||
inline int GetNextHPEvent() const { return nexthpevent; }
|
||||
void SetNextHPEvent( int hpevent );
|
||||
void SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse, float velocity= 4.0);
|
||||
void SendItemAnimation(Mob *to, const EQEmu::ItemBase *item, EQEmu::skills::SkillType skillInUse, float velocity = 4.0);
|
||||
inline int& GetNextIncHPEvent() { return nextinchpevent; }
|
||||
void SetNextIncHPEvent( int inchpevent );
|
||||
|
||||
@@ -878,6 +937,8 @@ public:
|
||||
Timer *GetSpecialAbilityTimer(int ability);
|
||||
void ClearSpecialAbilities();
|
||||
void ProcessSpecialAbilities(const std::string &str);
|
||||
bool IsMoved() { return moved; }
|
||||
void SetMoved(bool moveflag) { moved = moveflag; }
|
||||
|
||||
Shielders_Struct shielder[MAX_SHIELDERS];
|
||||
Trade* trade;
|
||||
@@ -889,8 +950,8 @@ public:
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; }
|
||||
|
||||
inline bool IsTrackable() const { return(trackable); }
|
||||
Timer* GetAIThinkTimer() { return AIthink_timer.get(); }
|
||||
Timer* GetAIMovementTimer() { return AImovement_timer.get(); }
|
||||
Timer* GetAIThinkTimer() { return AI_think_timer.get(); }
|
||||
Timer* GetAIMovementTimer() { return AI_movement_timer.get(); }
|
||||
Timer GetAttackTimer() { return attack_timer; }
|
||||
Timer GetAttackDWTimer() { return attack_dw_timer; }
|
||||
inline bool IsFindable() { return findable; }
|
||||
@@ -900,6 +961,7 @@ public:
|
||||
inline virtual bool IsBlockedBuff(int16 SpellID) { return false; }
|
||||
inline virtual bool IsBlockedPetBuff(int16 SpellID) { return false; }
|
||||
|
||||
std::string GetGlobal(const char *varname);
|
||||
void SetGlobal(const char *varname, const char *newvalue, int options, const char *duration, Mob *other = nullptr);
|
||||
void TarGlobal(const char *varname, const char *value, const char *duration, int npcid, int charid, int zoneid);
|
||||
void DelGlobal(const char *varname);
|
||||
@@ -908,8 +970,8 @@ public:
|
||||
inline uint16 GetEmoteID() { return emoteid; }
|
||||
|
||||
bool HasSpellEffect(int effectid);
|
||||
int mod_effect_value(int effect_value, uint16 spell_id, int effect_type, Mob* caster);
|
||||
float mod_hit_chance(float chancetohit, SkillUseTypes skillinuse, Mob* attacker);
|
||||
int mod_effect_value(int effect_value, uint16 spell_id, int effect_type, Mob* caster, uint16 caster_id);
|
||||
float mod_hit_chance(float chancetohit, EQEmu::skills::SkillType skillinuse, Mob* attacker);
|
||||
float mod_riposte_chance(float ripostchance, Mob* attacker);
|
||||
float mod_block_chance(float blockchance, Mob* attacker);
|
||||
float mod_parry_chance(float parrychance, Mob* attacker);
|
||||
@@ -920,7 +982,7 @@ public:
|
||||
int32 mod_kick_damage(int32 dmg);
|
||||
int32 mod_bash_damage(int32 dmg);
|
||||
int32 mod_frenzy_damage(int32 dmg);
|
||||
int32 mod_monk_special_damage(int32 ndamage, SkillUseTypes skill_type);
|
||||
int32 mod_monk_special_damage(int32 ndamage, EQEmu::skills::SkillType skill_type);
|
||||
int32 mod_backstab_damage(int32 ndamage);
|
||||
int mod_archery_bonus_chance(int bonuschance, const ItemInst* RangeWeapon);
|
||||
uint32 mod_archery_bonus_damage(uint32 MaxDmg, const ItemInst* RangeWeapon);
|
||||
@@ -939,28 +1001,62 @@ public:
|
||||
uint32 Tune_GetMeanDamage(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg = 0,int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
|
||||
void Tune_FindATKByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int ac_override=0,int Msg =0);
|
||||
void Tune_FindACByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int atk_override=0,int Msg =0);
|
||||
float Tune_CheckHitChance(Mob* defender, Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod, int Msg = 1,int acc_override=0, int avoid_override=0, int add_acc=0, int add_avoid = 0);
|
||||
float Tune_CheckHitChance(Mob* defender, Mob* attacker, EQEmu::skills::SkillType skillinuse, int Hand, int16 chance_mod, int Msg = 1, int acc_override = 0, int avoid_override = 0, int add_acc = 0, int add_avoid = 0);
|
||||
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
|
||||
void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0);
|
||||
|
||||
//aa new
|
||||
uint32 GetAA(uint32 rank_id, uint32 *charges = nullptr) const;
|
||||
uint32 GetAAByAAID(uint32 aa_id, uint32 *charges = nullptr) const;
|
||||
bool SetAA(uint32 rank_id, uint32 new_value, uint32 charges = 0);
|
||||
void ClearAAs() { aa_ranks.clear(); }
|
||||
bool CanUseAlternateAdvancementRank(AA::Rank *rank);
|
||||
bool CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant);
|
||||
int GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in);
|
||||
void ExpendAlternateAdvancementCharge(uint32 aa_id);
|
||||
void CalcAABonuses(StatBonuses* newbon);
|
||||
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
||||
bool CheckAATimer(int timer);
|
||||
|
||||
int NPCAssistCap() { return npc_assist_cap; }
|
||||
void AddAssistCap() { ++npc_assist_cap; }
|
||||
void DelAssistCap() { --npc_assist_cap; }
|
||||
void ResetAssistCap() { npc_assist_cap = 0; }
|
||||
|
||||
// Bots HealRotation methods
|
||||
#ifdef BOTS
|
||||
bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); }
|
||||
bool JoinHealRotationTargetPool(std::shared_ptr<HealRotation>* heal_rotation);
|
||||
bool LeaveHealRotationTargetPool();
|
||||
|
||||
uint32 HealRotationHealCount();
|
||||
uint32 HealRotationExtendedHealCount();
|
||||
float HealRotationHealFrequency();
|
||||
float HealRotationExtendedHealFrequency();
|
||||
|
||||
const std::shared_ptr<HealRotation>* TargetOfHealRotation() const { return &m_target_of_heal_rotation; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const EQEmu::skills::SkillType attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, int special = 0);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
float _GetMovementSpeed(int mod) const;
|
||||
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, bool checkZ);
|
||||
int _GetWalkSpeed() const;
|
||||
int _GetRunSpeed() const;
|
||||
int _GetFearSpeed() const;
|
||||
virtual bool MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ);
|
||||
|
||||
virtual bool AI_EngagedCastCheck() { return(false); }
|
||||
virtual bool AI_PursueCastCheck() { return(false); }
|
||||
virtual bool AI_IdleCastCheck() { return(false); }
|
||||
|
||||
|
||||
bool IsFullHP;
|
||||
bool moved;
|
||||
|
||||
std::vector<uint16> RampageArray;
|
||||
std::map<std::string, std::string> m_EntityVariables;
|
||||
|
||||
int16 SkillDmgTaken_Mod[HIGHEST_SKILL+2];
|
||||
int16 SkillDmgTaken_Mod[EQEmu::skills::HIGHEST_SKILL + 2];
|
||||
int16 Vulnerability_Mod[HIGHEST_RESIST+2];
|
||||
bool m_AllowBeneficial;
|
||||
bool m_DisableMelee;
|
||||
@@ -971,6 +1067,12 @@ protected:
|
||||
uint16 entity_id_being_looted; //the id of the entity being looted, 0 if not looting.
|
||||
uint8 texture;
|
||||
uint8 helmtexture;
|
||||
uint8 armtexture;
|
||||
uint8 bracertexture;
|
||||
uint8 handtexture;
|
||||
uint8 legtexture;
|
||||
uint8 feettexture;
|
||||
bool multitexture;
|
||||
|
||||
int AC;
|
||||
int32 ATK;
|
||||
@@ -1015,6 +1117,13 @@ protected:
|
||||
uint32 follow_dist;
|
||||
bool no_target_hotkey;
|
||||
|
||||
uint32 m_PlayerState;
|
||||
uint32 GetPlayerState() { return m_PlayerState; }
|
||||
void AddPlayerState(uint32 new_state) { m_PlayerState |= new_state; }
|
||||
void RemovePlayerState(uint32 old_state) { m_PlayerState &= ~old_state; }
|
||||
void SendAddPlayerState(PlayerState new_state);
|
||||
void SendRemovePlayerState(PlayerState old_state);
|
||||
|
||||
uint8 gender;
|
||||
uint16 race;
|
||||
uint8 base_gender;
|
||||
@@ -1031,31 +1140,39 @@ protected:
|
||||
float base_size;
|
||||
float size;
|
||||
float runspeed;
|
||||
float walkspeed;
|
||||
float fearspeed;
|
||||
int base_runspeed;
|
||||
int base_walkspeed;
|
||||
int base_fearspeed;
|
||||
int current_speed;
|
||||
|
||||
uint32 pLastChange;
|
||||
bool held;
|
||||
bool nocast;
|
||||
bool focused;
|
||||
bool spawned;
|
||||
void CalcSpellBonuses(StatBonuses* newbon);
|
||||
virtual void CalcBonuses();
|
||||
void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false); // hand = MainCharm?
|
||||
void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false); // hand = SlotCharm?
|
||||
bool PassLimitToSkill(uint16 spell_id, uint16 skill);
|
||||
bool PassLimitClass(uint32 Classes_, uint16 Class_);
|
||||
void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
|
||||
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on);
|
||||
virtual float GetProcChances(float ProcBonus, uint16 hand = MainPrimary);
|
||||
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = MainPrimary, Mob *on = nullptr);
|
||||
void TryDefensiveProc(Mob *on, uint16 hand = EQEmu::legacy::SlotPrimary);
|
||||
void TryWeaponProc(const ItemInst* inst, const EQEmu::ItemBase* weapon, Mob *on, uint16 hand = EQEmu::legacy::SlotPrimary);
|
||||
void TrySpellProc(const ItemInst* inst, const EQEmu::ItemBase* weapon, Mob *on, uint16 hand = EQEmu::legacy::SlotPrimary);
|
||||
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = EQEmu::legacy::SlotPrimary);
|
||||
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on, int level_override = -1);
|
||||
virtual float GetProcChances(float ProcBonus, uint16 hand = EQEmu::legacy::SlotPrimary);
|
||||
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = EQEmu::legacy::SlotPrimary, Mob *on = nullptr);
|
||||
virtual float GetSpecialProcChances(uint16 hand);
|
||||
virtual float GetAssassinateProcChances(uint16 ReuseTime);
|
||||
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm?
|
||||
uint16 GetWeaponSpeedbyHand(uint16 hand);
|
||||
int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemBase *weapon_item);
|
||||
int GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate = nullptr);
|
||||
int GetKickDamage();
|
||||
int GetBashDamage();
|
||||
virtual void ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg);
|
||||
virtual void ApplySpecialAttackMod(EQEmu::skills::SkillType skill, int32 &dmg, int32 &mindmg);
|
||||
virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
|
||||
void CalculateNewFearpoint();
|
||||
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
@@ -1063,6 +1180,8 @@ protected:
|
||||
void PrintRoute();
|
||||
|
||||
virtual float GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 ItemProcRate = 0);
|
||||
int16 GetSympatheticSpellProcRate(uint16 spell_id);
|
||||
uint16 GetSympatheticSpellProcID(uint16 spell_id);
|
||||
|
||||
enum {MAX_PROCS = 4};
|
||||
tProc PermaProcs[MAX_PROCS];
|
||||
@@ -1077,7 +1196,7 @@ protected:
|
||||
|
||||
glm::vec4 m_Delta;
|
||||
|
||||
LightProfile_Struct m_Light;
|
||||
EQEmu::LightSourceProfile m_Light;
|
||||
|
||||
float fixedZ;
|
||||
EmuAppearance _appearance;
|
||||
@@ -1100,16 +1219,17 @@ protected:
|
||||
int attacked_count;
|
||||
bool delaytimer;
|
||||
uint16 casting_spell_targetid;
|
||||
uint16 casting_spell_slot;
|
||||
EQEmu::CastingSlot casting_spell_slot;
|
||||
uint16 casting_spell_mana;
|
||||
uint32 casting_spell_inventory_slot;
|
||||
uint32 casting_spell_timer;
|
||||
uint32 casting_spell_timer_duration;
|
||||
uint32 casting_spell_type;
|
||||
int16 casting_spell_resist_adjust;
|
||||
uint32 casting_spell_aa_id;
|
||||
bool casting_spell_checks;
|
||||
uint16 bardsong;
|
||||
uint8 bardsong_slot;
|
||||
EQEmu::CastingSlot bardsong_slot;
|
||||
uint32 bardsong_target_id;
|
||||
|
||||
bool ActiveProjectileATK;
|
||||
@@ -1134,7 +1254,7 @@ protected:
|
||||
uint32 drakkin_heritage;
|
||||
uint32 drakkin_tattoo;
|
||||
uint32 drakkin_details;
|
||||
uint32 armor_tint[_MaterialCount];
|
||||
EQEmu::TintProfile armor_tint;
|
||||
|
||||
uint8 aa_title;
|
||||
|
||||
@@ -1153,6 +1273,7 @@ protected:
|
||||
bool offhand;
|
||||
bool has_shieldequiped;
|
||||
bool has_twohandbluntequiped;
|
||||
bool has_twohanderequipped;
|
||||
bool has_numhits;
|
||||
bool has_MGB;
|
||||
bool has_ProjectIllusion;
|
||||
@@ -1160,6 +1281,7 @@ protected:
|
||||
bool last_los_check;
|
||||
bool pseudo_rooted;
|
||||
bool endur_upkeep;
|
||||
bool degenerating_effects; // true if we have a buff that needs to be recalced every tick
|
||||
|
||||
// Bind wound
|
||||
Timer bindwound_timer;
|
||||
@@ -1178,14 +1300,15 @@ protected:
|
||||
uint32 maxLastFightingDelayMoving;
|
||||
float pAggroRange;
|
||||
float pAssistRange;
|
||||
std::unique_ptr<Timer> AIthink_timer;
|
||||
std::unique_ptr<Timer> AImovement_timer;
|
||||
std::unique_ptr<Timer> AItarget_check_timer;
|
||||
std::unique_ptr<Timer> AI_think_timer;
|
||||
std::unique_ptr<Timer> AI_movement_timer;
|
||||
std::unique_ptr<Timer> AI_target_check_timer;
|
||||
bool movetimercompleted;
|
||||
bool permarooted;
|
||||
std::unique_ptr<Timer> AIscanarea_timer;
|
||||
std::unique_ptr<Timer> AIwalking_timer;
|
||||
std::unique_ptr<Timer> AIfeignremember_timer;
|
||||
std::unique_ptr<Timer> AI_scan_area_timer;
|
||||
std::unique_ptr<Timer> AI_walking_timer;
|
||||
std::unique_ptr<Timer> AI_feign_remember_timer;
|
||||
std::unique_ptr<Timer> AI_check_signal_timer;
|
||||
uint32 pLastFightingDelayMoving;
|
||||
HateList hate_list;
|
||||
std::set<uint32> feign_memory_list;
|
||||
@@ -1216,10 +1339,15 @@ protected:
|
||||
glm::vec4 m_CurrentWayPoint;
|
||||
int cur_wp_pause;
|
||||
|
||||
bool PrimaryAggro;
|
||||
bool AssistAggro;
|
||||
int npc_assist_cap;
|
||||
Timer assist_cap_timer; // clear assist cap so more nearby mobs can be called for help
|
||||
|
||||
|
||||
int patrol;
|
||||
glm::vec3 m_FearWalkTarget;
|
||||
bool curfp;
|
||||
bool currently_fleeing;
|
||||
|
||||
// Pathing
|
||||
//
|
||||
@@ -1273,9 +1401,17 @@ protected:
|
||||
bool bEnraged;
|
||||
bool destructibleobject;
|
||||
|
||||
std::unordered_map<uint32, std::pair<uint32, uint32>> aa_ranks;
|
||||
Timer aa_timers[aaTimerMax];
|
||||
|
||||
private:
|
||||
void _StopSong(); //this is not what you think it is
|
||||
Mob* target;
|
||||
|
||||
#ifdef BOTS
|
||||
std::shared_ptr<HealRotation> m_target_of_heal_rotation;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+307
-403
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,6 @@ class ItemInst;
|
||||
class Spawn2;
|
||||
struct Consider_Struct;
|
||||
struct DBTradeskillRecipe_Struct;
|
||||
struct Item_Struct;
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
@@ -26,7 +25,7 @@ void Zone::mod_repop() { return; }
|
||||
void NPC::mod_prespawn(Spawn2 *sp) { return; }
|
||||
|
||||
//Base damage from NPC::Attack
|
||||
int NPC::mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other) { return(damage); }
|
||||
int NPC::mod_npc_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const EQEmu::ItemBase* weapon, Mob* other) { return(damage); }
|
||||
|
||||
//Mob c has been given credit for a kill. This is called after the regular EVENT_KILLED_MERIT event.
|
||||
void NPC::mod_npc_killed_merit(Mob* c) { return; }
|
||||
@@ -35,7 +34,7 @@ void NPC::mod_npc_killed_merit(Mob* c) { return; }
|
||||
void NPC::mod_npc_killed(Mob* oos) { return; }
|
||||
|
||||
//Base damage from Client::Attack - can cover myriad skill types
|
||||
int Client::mod_client_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemInst* weapon, Mob* other) { return(damage); }
|
||||
int Client::mod_client_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const ItemInst* weapon, Mob* other) { return(damage); }
|
||||
|
||||
//message is char[4096], don't screw it up. Return true for normal behavior, false to return immediately.
|
||||
// Channels:
|
||||
@@ -55,7 +54,7 @@ bool Client::mod_client_message(char* message, uint8 chan_num) { return(true); }
|
||||
|
||||
//Skillup override. When this is called the regular skillup check has failed. Return false to proceed with default behavior.
|
||||
//This will NOT allow a client to increase skill past a cap.
|
||||
bool Client::mod_can_increase_skill(SkillUseTypes skillid, Mob* against_who) { return(false); }
|
||||
bool Client::mod_can_increase_skill(EQEmu::skills::SkillType skillid, Mob* against_who) { return(false); }
|
||||
|
||||
//chance of general skill increase, rolled against 0-99 where higher chance is better.
|
||||
int16 Client::mod_increase_skill_chance(int16 chance, Mob* against_who) { return(chance); }
|
||||
@@ -104,14 +103,14 @@ int32 Client::mod_client_xp(int32 in_xp, NPC *npc) { return(in_xp); }
|
||||
uint32 Client::mod_client_xp_for_level(uint32 xp, uint16 check_level) { return(xp); }
|
||||
|
||||
//Food and drink values as computed by consume requests. Return < 0 to abort the request.
|
||||
int Client::mod_food_value(const Item_Struct *item, int change) { return(change); }
|
||||
int Client::mod_drink_value(const Item_Struct *item, int change) { return(change); }
|
||||
int Client::mod_food_value(const EQEmu::ItemBase *item, int change) { return(change); }
|
||||
int Client::mod_drink_value(const EQEmu::ItemBase *item, int change) { return(change); }
|
||||
|
||||
//effect_vallue - Spell effect value as calculated by default formulas. You will want to ignore effects that don't lend themselves to scaling - pet ID's, gate coords, etc.
|
||||
int Mob::mod_effect_value(int effect_value, uint16 spell_id, int effect_type, Mob* caster) { return(effect_value); }
|
||||
int Mob::mod_effect_value(int effect_value, uint16 spell_id, int effect_type, Mob* caster, uint16 caster_id) { return(effect_value); }
|
||||
|
||||
//chancetohit - 0 to 100 percent - set over 1000 for a guaranteed hit
|
||||
float Mob::mod_hit_chance(float chancetohit, SkillUseTypes skillinuse, Mob* attacker) { return(chancetohit); }
|
||||
float Mob::mod_hit_chance(float chancetohit, EQEmu::skills::SkillType skillinuse, Mob* attacker) { return(chancetohit); }
|
||||
|
||||
//Final riposte chance
|
||||
float Mob::mod_riposte_chance(float ripostechance, Mob* attacker) { return(ripostechance); }
|
||||
@@ -143,7 +142,7 @@ int32 Mob::mod_bash_damage(int32 dmg) { return(dmg); }
|
||||
int32 Mob::mod_frenzy_damage(int32 dmg) { return(dmg); }
|
||||
|
||||
//Special attack damage after all other bonuses are applied.
|
||||
int32 Mob::mod_monk_special_damage(int32 ndamage, SkillUseTypes skill_type) { return(ndamage); }
|
||||
int32 Mob::mod_monk_special_damage(int32 ndamage, EQEmu::skills::SkillType skill_type) { return(ndamage); }
|
||||
|
||||
//ndamage - Backstab damage as calculated by default formulas
|
||||
int32 Mob::mod_backstab_damage(int32 ndamage) { return(ndamage); }
|
||||
|
||||
+154
-98
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
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
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/mutex.h"
|
||||
#include "../common/version.h"
|
||||
|
||||
#include "../common/packet_dump_file.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/guilds.h"
|
||||
@@ -53,6 +52,10 @@
|
||||
#include "zone.h"
|
||||
#include "queryserv.h"
|
||||
#include "command.h"
|
||||
#ifdef BOTS
|
||||
#include "bot_command.h"
|
||||
#include "bot_database.h"
|
||||
#endif
|
||||
#include "zone_config.h"
|
||||
#include "titles.h"
|
||||
#include "guild_mgr.h"
|
||||
@@ -60,7 +63,6 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "embparser.h"
|
||||
#include "lua_parser.h"
|
||||
|
||||
#include "questmgr.h"
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
@@ -68,7 +70,6 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
@@ -89,7 +90,7 @@
|
||||
#endif
|
||||
|
||||
volatile bool RunLoops = true;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
|
||||
TimeoutManager timeout_manager;
|
||||
NetConnection net;
|
||||
@@ -97,7 +98,6 @@ EntityList entity_list;
|
||||
WorldServer worldserver;
|
||||
uint32 numclients = 0;
|
||||
char errorname[32];
|
||||
uint16 adverrornum = 0;
|
||||
extern Zone* zone;
|
||||
EQStreamFactory eqsf(ZoneStream);
|
||||
npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
||||
@@ -106,10 +106,9 @@ QueryServ *QServ = 0;
|
||||
TaskManager *taskmanager = 0;
|
||||
QuestParserCollection *parse = 0;
|
||||
EQEmuLogSys Log;
|
||||
|
||||
const SPDat_Spell_Struct* spells;
|
||||
void LoadSpells(EQEmu::MemoryMappedFile **mmf);
|
||||
int32 SPDAT_RECORDS = -1;
|
||||
const ZoneConfig *Config;
|
||||
|
||||
void Shutdown();
|
||||
extern void MapOpcodes();
|
||||
@@ -117,32 +116,101 @@ extern void MapOpcodes();
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformZone);
|
||||
Log.LoadLogSettingsDefaults();
|
||||
|
||||
set_exception_handler();
|
||||
register_remote_call_handlers();
|
||||
|
||||
const char *zone_name;
|
||||
#ifdef USE_MAP_MMFS
|
||||
if (argc == 3 && strcasecmp(argv[1], "convert_map") == 0) {
|
||||
if (!ZoneConfig::LoadConfig())
|
||||
return 1;
|
||||
Config = ZoneConfig::get();
|
||||
|
||||
std::string mapfile = argv[2];
|
||||
std::transform(mapfile.begin(), mapfile.end(), mapfile.begin(), ::tolower);
|
||||
std::string filename = Config->MapDir;
|
||||
filename += mapfile;
|
||||
|
||||
auto m = new Map();
|
||||
auto success = m->Load(filename, true);
|
||||
delete m;
|
||||
std::cout << mapfile.c_str() << " conversion " << (success ? "succeeded" : "failed") << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
QServ = new QueryServ;
|
||||
|
||||
if(argc == 3) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
||||
if(!ZoneConfig::LoadConfig()) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading server configuration failed.");
|
||||
return 1;
|
||||
}
|
||||
Config = ZoneConfig::get();
|
||||
|
||||
const char *zone_name;
|
||||
uint32 instance_id = 0;
|
||||
std::string z_name;
|
||||
if(argc == 4) {
|
||||
instance_id = atoi(argv[3]);
|
||||
worldserver.SetLauncherName(argv[2]);
|
||||
worldserver.SetLaunchedName(argv[1]);
|
||||
if(strncmp(argv[1], "dynamic_", 8) == 0) {
|
||||
//dynamic zone with a launcher name correlation
|
||||
auto zone_port = SplitString(argv[1], ':');
|
||||
|
||||
if(!zone_port.empty()) {
|
||||
z_name = zone_port[0];
|
||||
}
|
||||
|
||||
if(zone_port.size() > 1) {
|
||||
std::string p_name = zone_port[1];
|
||||
Config->SetZonePort(atoi(p_name.c_str()));
|
||||
}
|
||||
|
||||
worldserver.SetLaunchedName(z_name.c_str());
|
||||
if(strncmp(z_name.c_str(), "dynamic_", 8) == 0) {
|
||||
zone_name = ".";
|
||||
}
|
||||
else {
|
||||
zone_name = z_name.c_str();
|
||||
}
|
||||
} else if(argc == 3) {
|
||||
worldserver.SetLauncherName(argv[2]);
|
||||
auto zone_port = SplitString(argv[1], ':');
|
||||
|
||||
if(!zone_port.empty()) {
|
||||
z_name = zone_port[0];
|
||||
}
|
||||
|
||||
if(zone_port.size() > 1) {
|
||||
std::string p_name = zone_port[1];
|
||||
Config->SetZonePort(atoi(p_name.c_str()));
|
||||
}
|
||||
|
||||
worldserver.SetLaunchedName(z_name.c_str());
|
||||
if(strncmp(z_name.c_str(), "dynamic_", 8) == 0) {
|
||||
zone_name = ".";
|
||||
} else {
|
||||
zone_name = argv[1];
|
||||
worldserver.SetLaunchedName(zone_name);
|
||||
zone_name = z_name.c_str();
|
||||
}
|
||||
} else if (argc == 2) {
|
||||
worldserver.SetLauncherName("NONE");
|
||||
worldserver.SetLaunchedName(argv[1]);
|
||||
if(strncmp(argv[1], "dynamic_", 8) == 0) {
|
||||
//dynamic zone with a launcher name correlation
|
||||
auto zone_port = SplitString(argv[1], ':');
|
||||
|
||||
if(!zone_port.empty()) {
|
||||
z_name = zone_port[0];
|
||||
}
|
||||
|
||||
if(zone_port.size() > 1) {
|
||||
std::string p_name = zone_port[1];
|
||||
Config->SetZonePort(atoi(p_name.c_str()));
|
||||
}
|
||||
|
||||
worldserver.SetLaunchedName(z_name.c_str());
|
||||
if(strncmp(z_name.c_str(), "dynamic_", 8) == 0) {
|
||||
zone_name = ".";
|
||||
} else {
|
||||
zone_name = argv[1];
|
||||
worldserver.SetLaunchedName(zone_name);
|
||||
}
|
||||
else {
|
||||
zone_name = z_name.c_str();
|
||||
}
|
||||
} else {
|
||||
zone_name = ".";
|
||||
@@ -150,15 +218,8 @@ int main(int argc, char** argv) {
|
||||
worldserver.SetLauncherName("NONE");
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
||||
if (!ZoneConfig::LoadConfig()) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading server configuration failed.");
|
||||
return 1;
|
||||
}
|
||||
const ZoneConfig *Config = ZoneConfig::get();
|
||||
|
||||
worldserver.SetPassword(Config->SharedKey.c_str());
|
||||
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Connecting to MySQL...");
|
||||
if (!database.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
@@ -170,6 +231,18 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
if (!botdb.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(),
|
||||
Config->DatabaseDB.c_str(),
|
||||
Config->DatabasePort)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Cannot continue without a bots database connection.");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register Log System and Settings */
|
||||
Log.OnLogHookCallBackZone(&Zone::GMSayHookCallBackProcess);
|
||||
database.LoadLogSettings(Log.log_settings);
|
||||
@@ -205,41 +278,50 @@ int main(int argc, char** argv) {
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Mapping Incoming Opcodes");
|
||||
MapOpcodes();
|
||||
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading Variables");
|
||||
database.LoadVariables();
|
||||
|
||||
|
||||
std::string hotfix_name;
|
||||
if(database.GetVariable("hotfix_name", hotfix_name)) {
|
||||
if(!hotfix_name.empty()) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Current hotfix in use: '%s'", hotfix_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading zone names");
|
||||
database.LoadZoneNames();
|
||||
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading items");
|
||||
if (!database.LoadItems()) {
|
||||
if(!database.LoadItems(hotfix_name)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading items FAILED!");
|
||||
Log.Out(Logs::General, Logs::Error, "Failed. But ignoring error and going on...");
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading npc faction lists");
|
||||
if (!database.LoadNPCFactionLists()) {
|
||||
if(!database.LoadNPCFactionLists(hotfix_name)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading npcs faction lists FAILED!");
|
||||
return 1;
|
||||
}
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading loot tables");
|
||||
if (!database.LoadLoot()) {
|
||||
if(!database.LoadLoot(hotfix_name)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading loot FAILED!");
|
||||
return 1;
|
||||
}
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading skill caps");
|
||||
if (!database.LoadSkillCaps()) {
|
||||
if(!database.LoadSkillCaps(std::string(hotfix_name))) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading skill caps FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading spells");
|
||||
EQEmu::MemoryMappedFile *mmf = nullptr;
|
||||
LoadSpells(&mmf);
|
||||
if(!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading spells FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading base data");
|
||||
if (!database.LoadBaseData()) {
|
||||
if(!database.LoadBaseData(hotfix_name)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading base data FAILED!");
|
||||
return 1;
|
||||
}
|
||||
@@ -253,9 +335,6 @@ int main(int argc, char** argv) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading titles");
|
||||
title_manager.LoadTitles();
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading AA effects");
|
||||
database.LoadAAEffects();
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading tributes");
|
||||
database.LoadTributes();
|
||||
|
||||
@@ -271,21 +350,30 @@ int main(int argc, char** argv) {
|
||||
|
||||
//rules:
|
||||
{
|
||||
char tmp[64];
|
||||
if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading rule set '%s'", tmp);
|
||||
if(!RuleManager::Instance()->LoadRules(&database, tmp)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load ruleset '%s', falling back to defaults.", tmp);
|
||||
std::string tmp;
|
||||
if (database.GetVariable("RuleSet", tmp)) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading rule set '%s'", tmp.c_str());
|
||||
if(!RuleManager::Instance()->LoadRules(&database, tmp.c_str())) {
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to load ruleset '%s', falling back to defaults.", tmp.c_str());
|
||||
}
|
||||
} else {
|
||||
if(!RuleManager::Instance()->LoadRules(&database, "default")) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "No rule set configured, using default rules");
|
||||
} else {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loaded default rule set 'default'", tmp);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loaded default rule set 'default'", tmp.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading bot commands");
|
||||
int botretval = bot_command_init();
|
||||
if (botretval<0)
|
||||
Log.Out(Logs::General, Logs::Error, "Bot command loading FAILED");
|
||||
else
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "%d bot commands loaded", botretval);
|
||||
#endif
|
||||
|
||||
if(RuleB(TaskSystem, EnableTaskSystem)) {
|
||||
Log.Out(Logs::General, Logs::Tasks, "[INIT] Loading Tasks");
|
||||
taskmanager = new TaskManager;
|
||||
@@ -294,13 +382,17 @@ int main(int argc, char** argv) {
|
||||
|
||||
parse = new QuestParserCollection();
|
||||
#ifdef LUA_EQEMU
|
||||
LuaParser *lua_parser = new LuaParser();
|
||||
auto lua_parser = new LuaParser();
|
||||
parse->RegisterQuestInterface(lua_parser, "lua");
|
||||
#endif
|
||||
|
||||
#ifdef EMBPERL
|
||||
PerlembParser *perl_parser = new PerlembParser();
|
||||
auto perl_parser = new PerlembParser();
|
||||
parse->RegisterQuestInterface(perl_parser, "pl");
|
||||
|
||||
/* Load Perl Event Export Settings */
|
||||
parse->LoadPerlEventExportSettings(parse->perl_event_export_settings);
|
||||
|
||||
#endif
|
||||
|
||||
//now we have our parser, load the quests
|
||||
@@ -321,7 +413,7 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
if (!strlen(zone_name) || !strcmp(zone_name,".")) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Entering sleep mode");
|
||||
} else if (!Zone::Bootup(database.GetZoneID(zone_name), 0, true)) { //todo: go above and fix this to allow cmd line instance
|
||||
} else if (!Zone::Bootup(database.GetZoneID(zone_name), instance_id, true)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Zone Bootup failed :: Zone::Bootup");
|
||||
zone = 0;
|
||||
}
|
||||
@@ -351,10 +443,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
worldserver.Process();
|
||||
|
||||
if (!eqsf.IsOpen() && Config->ZonePort!=0) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d",Config->ZonePort);
|
||||
if (!eqsf.IsOpen() && Config->ZonePort != 0) {
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
|
||||
if (!eqsf.Open(Config->ZonePort)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to open port %d",Config->ZonePort);
|
||||
Log.Out(Logs::General, Logs::Error, "Failed to open port %d", Config->ZonePort);
|
||||
ZoneConfig::SetZonePort(0);
|
||||
worldserver.Disconnect();
|
||||
worldwasconnected = false;
|
||||
@@ -368,7 +460,7 @@ int main(int argc, char** argv) {
|
||||
//structures and opcodes for that patch.
|
||||
struct in_addr in;
|
||||
in.s_addr = eqss->GetRemoteIP();
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in),ntohs(eqss->GetRemotePort()));
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in), ntohs(eqss->GetRemotePort()));
|
||||
stream_identifier.AddStream(eqss); //takes the stream
|
||||
}
|
||||
|
||||
@@ -381,7 +473,7 @@ int main(int argc, char** argv) {
|
||||
struct in_addr in;
|
||||
in.s_addr = eqsi->GetRemoteIP();
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "New client from %s:%d", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
|
||||
Client* client = new Client(eqsi);
|
||||
auto client = new Client(eqsi);
|
||||
entity_list.AddClient(client);
|
||||
}
|
||||
|
||||
@@ -400,12 +492,12 @@ int main(int argc, char** argv) {
|
||||
worldwasconnected = true;
|
||||
}
|
||||
else {
|
||||
if (worldwasconnected && ZoneLoaded)
|
||||
if (worldwasconnected && is_zone_loaded)
|
||||
entity_list.ChannelMessageFromWorld(0, 0, 6, 0, 0, "WARNING: World server connection lost");
|
||||
worldwasconnected = false;
|
||||
}
|
||||
|
||||
if (ZoneLoaded && zoneupdate_timer.Check()) {
|
||||
if (is_zone_loaded && zoneupdate_timer.Check()) {
|
||||
{
|
||||
if(net.group_timer.Enabled() && net.group_timer.Check())
|
||||
entity_list.GroupProcess();
|
||||
@@ -428,6 +520,7 @@ int main(int argc, char** argv) {
|
||||
entity_list.Process();
|
||||
entity_list.MobProcess();
|
||||
entity_list.BeaconProcess();
|
||||
entity_list.EncounterProcess();
|
||||
|
||||
if (zone) {
|
||||
if(!zone->Process()) {
|
||||
@@ -475,7 +568,6 @@ int main(int argc, char** argv) {
|
||||
safe_delete(lua_parser);
|
||||
#endif
|
||||
|
||||
safe_delete(mmf);
|
||||
safe_delete(Config);
|
||||
|
||||
if (zone != 0)
|
||||
@@ -485,6 +577,9 @@ int main(int argc, char** argv) {
|
||||
worldserver.Disconnect();
|
||||
safe_delete(taskmanager);
|
||||
command_deinit();
|
||||
#ifdef BOTS
|
||||
bot_command_deinit();
|
||||
#endif
|
||||
safe_delete(parse);
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Proper zone shutdown complete.");
|
||||
Log.CloseFileLogs();
|
||||
@@ -541,16 +636,6 @@ uint32 NetConnection::GetIP(char* name)
|
||||
|
||||
}
|
||||
|
||||
void NetConnection::SaveInfo(char* address, uint32 port, char* waddress, char* filename) {
|
||||
|
||||
ZoneAddress = new char[strlen(address)+1];
|
||||
strcpy(ZoneAddress, address);
|
||||
ZonePort = port;
|
||||
WorldAddress = new char[strlen(waddress)+1];
|
||||
strcpy(WorldAddress, waddress);
|
||||
strn0cpy(ZoneFileName, filename, sizeof(ZoneFileName));
|
||||
}
|
||||
|
||||
NetConnection::NetConnection()
|
||||
:
|
||||
object_timer(5000),
|
||||
@@ -560,9 +645,6 @@ NetConnection::NetConnection()
|
||||
raid_timer(1000),
|
||||
trap_timer(1000)
|
||||
{
|
||||
ZonePort = 0;
|
||||
ZoneAddress = 0;
|
||||
WorldAddress = 0;
|
||||
group_timer.Disable();
|
||||
raid_timer.Disable();
|
||||
corpse_timer.Disable();
|
||||
@@ -572,32 +654,6 @@ NetConnection::NetConnection()
|
||||
}
|
||||
|
||||
NetConnection::~NetConnection() {
|
||||
if (ZoneAddress != 0)
|
||||
safe_delete_array(ZoneAddress);
|
||||
if (WorldAddress != 0)
|
||||
safe_delete_array(WorldAddress);
|
||||
}
|
||||
|
||||
void LoadSpells(EQEmu::MemoryMappedFile **mmf) {
|
||||
int records = database.GetMaxSpellID() + 1;
|
||||
|
||||
try {
|
||||
EQEmu::IPCMutex mutex("spells");
|
||||
mutex.Lock();
|
||||
*mmf = new EQEmu::MemoryMappedFile("shared/spells");
|
||||
uint32 size = (*mmf)->Size();
|
||||
if(size != (records * sizeof(SPDat_Spell_Struct))) {
|
||||
EQ_EXCEPT("Zone", "Unable to load spells: (*mmf)->Size() != records * sizeof(SPDat_Spell_Struct)");
|
||||
}
|
||||
|
||||
spells = reinterpret_cast<SPDat_Spell_Struct*>((*mmf)->Get());
|
||||
mutex.Unlock();
|
||||
} catch(std::exception &ex) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error loading spells: %s", ex.what());
|
||||
return;
|
||||
}
|
||||
|
||||
SPDAT_RECORDS = records;
|
||||
}
|
||||
|
||||
/* Update Window Title with relevant information */
|
||||
|
||||
+1
-11
@@ -16,8 +16,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifdef _WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -39,20 +39,10 @@ public:
|
||||
|
||||
uint32 GetIP();
|
||||
uint32 GetIP(char* name);
|
||||
void SaveInfo(char* address, uint32 port, char* waddress,char* filename);
|
||||
char* GetWorldAddress() { return WorldAddress; }
|
||||
char* GetZoneAddress() { return ZoneAddress; }
|
||||
char* GetZoneFileName() { return ZoneFileName; }
|
||||
uint32 GetZonePort() { return ZonePort; }
|
||||
Timer object_timer;
|
||||
Timer door_timer;
|
||||
Timer corpse_timer;
|
||||
Timer group_timer;
|
||||
Timer raid_timer;
|
||||
Timer trap_timer;
|
||||
private:
|
||||
uint16 ZonePort;
|
||||
char* ZoneAddress;
|
||||
char* WorldAddress;
|
||||
char ZoneFileName[50];
|
||||
};
|
||||
|
||||
+336
-232
@@ -24,20 +24,21 @@
|
||||
#include "../common/seperator.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/clientversions.h"
|
||||
#include "../common/emu_versions.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/item_struct.h"
|
||||
#include "../common/item_base.h"
|
||||
#include "../common/linked_list.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/say_link.h"
|
||||
|
||||
#include "aa.h"
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
#include "npc.h"
|
||||
#include "string_ids.h"
|
||||
#include "spawn2.h"
|
||||
#include "zone.h"
|
||||
#include "quest_parser_collection.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <stdio.h>
|
||||
@@ -53,7 +54,7 @@
|
||||
#endif
|
||||
|
||||
extern Zone* zone;
|
||||
extern volatile bool ZoneLoaded;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern EntityList entity_list;
|
||||
|
||||
NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int iflymode, bool IsCorpse)
|
||||
@@ -93,7 +94,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
d->drakkin_heritage,
|
||||
d->drakkin_tattoo,
|
||||
d->drakkin_details,
|
||||
(uint32*)d->armor_tint,
|
||||
d->armor_tint,
|
||||
0,
|
||||
d->see_invis, // pass see_invis/see_ivu flags to mob constructor
|
||||
d->see_invis_undead,
|
||||
@@ -103,14 +104,19 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
d->mana_regen,
|
||||
d->qglobal,
|
||||
d->maxlevel,
|
||||
d->scalerate ),
|
||||
d->scalerate,
|
||||
d->armtexture,
|
||||
d->bracertexture,
|
||||
d->handtexture,
|
||||
d->legtexture,
|
||||
d->feettexture),
|
||||
attacked_timer(CombatEventTimer_expire),
|
||||
swarm_timer(100),
|
||||
classattack_timer(1000),
|
||||
knightattack_timer(1000),
|
||||
assist_timer(AIassistcheck_delay),
|
||||
qglobal_purge_timer(30000),
|
||||
sendhpupdate_timer(1000),
|
||||
sendhpupdate_timer(2000),
|
||||
enraged_timer(1000),
|
||||
taunt_timer(TauntReuseTime * 1000),
|
||||
m_SpawnPoint(position),
|
||||
@@ -227,6 +233,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
npc_spells_id = 0;
|
||||
HasAISpell = false;
|
||||
HasAISpellEffects = false;
|
||||
innate_proc_spell_id = 0;
|
||||
|
||||
if(GetClass() == MERCERNARY_MASTER && RuleB(Mercs, AllowMercs))
|
||||
{
|
||||
@@ -271,8 +278,20 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
|
||||
//give NPCs skill values...
|
||||
int r;
|
||||
for(r = 0; r <= HIGHEST_SKILL; r++) {
|
||||
skills[r] = database.GetSkillCap(GetClass(),(SkillUseTypes)r,moblevel);
|
||||
for (r = 0; r <= EQEmu::skills::HIGHEST_SKILL; r++) {
|
||||
skills[r] = database.GetSkillCap(GetClass(), (EQEmu::skills::SkillType)r, moblevel);
|
||||
}
|
||||
// some overrides -- really we need to be able to set skills for mobs in the DB
|
||||
// There are some known low level SHM/BST pets that do not follow this, which supports
|
||||
// the theory of needing to be able to set skills for each mob separately
|
||||
if (moblevel > 50) {
|
||||
skills[EQEmu::skills::SkillDoubleAttack] = 250;
|
||||
skills[EQEmu::skills::SkillDualWield] = 250;
|
||||
} else if (moblevel > 3) {
|
||||
skills[EQEmu::skills::SkillDoubleAttack] = moblevel * 5;
|
||||
skills[EQEmu::skills::SkillDualWield] = skills[EQEmu::skills::SkillDoubleAttack];
|
||||
} else {
|
||||
skills[EQEmu::skills::SkillDoubleAttack] = moblevel * 5;
|
||||
}
|
||||
|
||||
if(d->trap_template > 0)
|
||||
@@ -286,7 +305,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if
|
||||
trap_list = trap_ent_iter->second;
|
||||
if(trap_list.size() > 0)
|
||||
{
|
||||
std::list<LDoNTrapTemplate*>::iterator trap_list_iter = trap_list.begin();
|
||||
auto trap_list_iter = trap_list.begin();
|
||||
std::advance(trap_list_iter, zone->random.Int(0, trap_list.size() - 1));
|
||||
LDoNTrapTemplate* tt = (*trap_list_iter);
|
||||
if(tt)
|
||||
@@ -462,7 +481,7 @@ void NPC::CheckMinMaxLevel(Mob *them)
|
||||
uint16 themlevel = them->GetLevel();
|
||||
uint8 material;
|
||||
|
||||
std::list<ServerLootItem_Struct*>::iterator cur = itemlist.begin();
|
||||
auto cur = itemlist.begin();
|
||||
while(cur != itemlist.end())
|
||||
{
|
||||
if(!(*cur))
|
||||
@@ -471,7 +490,7 @@ void NPC::CheckMinMaxLevel(Mob *them)
|
||||
if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level)
|
||||
{
|
||||
material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot);
|
||||
if (material != _MaterialInvalid)
|
||||
if (material != EQEmu::textures::TextureInvalid)
|
||||
SendWearChange(material);
|
||||
|
||||
cur = itemlist.erase(cur);
|
||||
@@ -505,19 +524,19 @@ void NPC::QueryLoot(Client* to)
|
||||
to->Message(0, "Coin: %ip %ig %is %ic", platinum, gold, silver, copper);
|
||||
|
||||
int x = 0;
|
||||
for(ItemList::iterator cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) {
|
||||
const Item_Struct* item = database.GetItem((*cur)->item_id);
|
||||
for (auto cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) {
|
||||
const EQEmu::ItemBase* item = database.GetItem((*cur)->item_id);
|
||||
if (item == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Database error, invalid item");
|
||||
continue;
|
||||
}
|
||||
|
||||
Client::TextLink linker;
|
||||
linker.SetLinkType(linker.linkItemData);
|
||||
EQEmu::SayLinkEngine linker;
|
||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
||||
linker.SetItemData(item);
|
||||
|
||||
auto item_link = linker.GenerateLink();
|
||||
|
||||
|
||||
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level);
|
||||
}
|
||||
|
||||
@@ -564,8 +583,7 @@ bool NPC::Process()
|
||||
{
|
||||
if (IsStunned() && stunned_timer.Check())
|
||||
{
|
||||
this->stunned = false;
|
||||
this->stunned_timer.Disable();
|
||||
Mob::UnStun();
|
||||
this->spun_timer.Disable();
|
||||
}
|
||||
|
||||
@@ -586,9 +604,10 @@ bool NPC::Process()
|
||||
|
||||
if(tic_timer.Check())
|
||||
{
|
||||
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
|
||||
BuffProcess();
|
||||
|
||||
if(curfp)
|
||||
if(currently_fleeing)
|
||||
ProcessFlee();
|
||||
|
||||
uint32 bonus = 0;
|
||||
@@ -646,7 +665,8 @@ bool NPC::Process()
|
||||
}
|
||||
}
|
||||
|
||||
if (sendhpupdate_timer.Check() && (IsTargeted() || (IsPet() && GetOwner() && GetOwner()->IsClient()))) {
|
||||
// we might actually want to reset in this check ... won't until issues arise at least :P
|
||||
if (sendhpupdate_timer.Check(false) && (IsTargeted() || (IsPet() && GetOwner() && GetOwner()->IsClient()))) {
|
||||
if(!IsFullHP || cur_hp<max_hp){
|
||||
SendHPUpdate();
|
||||
}
|
||||
@@ -694,8 +714,18 @@ bool NPC::Process()
|
||||
}
|
||||
|
||||
//Handle assists...
|
||||
if(assist_timer.Check() && IsEngaged() && !Charmed()) {
|
||||
if (assist_cap_timer.Check()) {
|
||||
if (NPCAssistCap() > 0)
|
||||
DelAssistCap();
|
||||
else
|
||||
assist_cap_timer.Disable();
|
||||
}
|
||||
|
||||
if (assist_timer.Check() && IsEngaged() && !Charmed() && !HasAssistAggro() &&
|
||||
NPCAssistCap() < RuleI(Combat, NPCAssistCap)) {
|
||||
entity_list.AIYellForHelp(this, GetTarget());
|
||||
if (NPCAssistCap() > 0 && !assist_cap_timer.Enabled())
|
||||
assist_cap_timer.Start(RuleI(Combat, NPCAssistCapTimer));
|
||||
}
|
||||
|
||||
if(qGlobals)
|
||||
@@ -717,18 +747,18 @@ uint32 NPC::CountLoot() {
|
||||
|
||||
void NPC::UpdateEquipmentLight()
|
||||
{
|
||||
m_Light.Type.Equipment = 0;
|
||||
m_Light.Level.Equipment = 0;
|
||||
|
||||
for (int index = MAIN_BEGIN; index < EmuConstants::EQUIPMENT_SIZE; ++index) {
|
||||
if (index == MainAmmo) { continue; }
|
||||
m_Light.Type[EQEmu::lightsource::LightEquipment] = 0;
|
||||
m_Light.Level[EQEmu::lightsource::LightEquipment] = 0;
|
||||
|
||||
for (int index = SLOT_BEGIN; index < EQEmu::legacy::EQUIPMENT_SIZE; ++index) {
|
||||
if (index == EQEmu::legacy::SlotAmmo) { continue; }
|
||||
|
||||
auto item = database.GetItem(equipment[index]);
|
||||
if (item == nullptr) { continue; }
|
||||
|
||||
if (m_Light.IsLevelGreater(item->Light, m_Light.Type.Equipment)) {
|
||||
m_Light.Type.Equipment = item->Light;
|
||||
m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment);
|
||||
if (EQEmu::lightsource::IsLevelGreater(item->Light, m_Light.Type[EQEmu::lightsource::LightEquipment])) {
|
||||
m_Light.Type[EQEmu::lightsource::LightEquipment] = item->Light;
|
||||
m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,17 +767,17 @@ void NPC::UpdateEquipmentLight()
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
if (item == nullptr) { continue; }
|
||||
|
||||
if (item->ItemClass != ItemClassCommon) { continue; }
|
||||
if (!item->IsClassCommon()) { continue; }
|
||||
if (item->Light < 9 || item->Light > 13) { continue; }
|
||||
|
||||
if (m_Light.TypeToLevel(item->Light))
|
||||
if (EQEmu::lightsource::TypeToLevel(item->Light))
|
||||
general_light_type = item->Light;
|
||||
}
|
||||
|
||||
if (m_Light.IsLevelGreater(general_light_type, m_Light.Type.Equipment))
|
||||
m_Light.Type.Equipment = general_light_type;
|
||||
if (EQEmu::lightsource::IsLevelGreater(general_light_type, m_Light.Type[EQEmu::lightsource::LightEquipment]))
|
||||
m_Light.Type[EQEmu::lightsource::LightEquipment] = general_light_type;
|
||||
|
||||
m_Light.Level.Equipment = m_Light.TypeToLevel(m_Light.Type.Equipment);
|
||||
m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]);
|
||||
}
|
||||
|
||||
void NPC::Depop(bool StartSpawnTimer) {
|
||||
@@ -815,6 +845,54 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::SpawnZoneController(){
|
||||
|
||||
if (!RuleB(Zone, UseZoneController))
|
||||
return false;
|
||||
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
|
||||
strncpy(npc_type->name, "zone_controller", 60);
|
||||
npc_type->cur_hp = 2000000000;
|
||||
npc_type->max_hp = 2000000000;
|
||||
npc_type->hp_regen = 100000000;
|
||||
npc_type->race = 240;
|
||||
npc_type->size = .1;
|
||||
npc_type->gender = 2;
|
||||
npc_type->class_ = 1;
|
||||
npc_type->deity = 1;
|
||||
npc_type->level = 200;
|
||||
npc_type->npc_id = ZONE_CONTROLLER_NPC_ID;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = 3;
|
||||
npc_type->runspeed = 0;
|
||||
npc_type->d_melee_texture1 = 0;
|
||||
npc_type->d_melee_texture2 = 0;
|
||||
npc_type->merchanttype = 0;
|
||||
npc_type->bodytype = 11;
|
||||
|
||||
npc_type->prim_melee_type = 28;
|
||||
npc_type->sec_melee_type = 28;
|
||||
|
||||
npc_type->findable = 0;
|
||||
npc_type->trackable = 0;
|
||||
|
||||
strcpy(npc_type->special_abilities, "12,1^13,1^14,1^15,1^16,1^17,1^19,1^22,1^24,1^25,1^28,1^31,1^35,1^39,1^42,1");
|
||||
|
||||
glm::vec4 point;
|
||||
point.x = 3000;
|
||||
point.y = 1000;
|
||||
point.z = 500;
|
||||
|
||||
auto npc = new NPC(npc_type, nullptr, point, FlyMode3);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
|
||||
entity_list.AddNPC(npc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) {
|
||||
if(spawncommand == 0 || spawncommand[0] == 0) {
|
||||
return 0;
|
||||
@@ -940,7 +1018,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
|
||||
}
|
||||
|
||||
//Time to create the NPC!!
|
||||
NPCType* npc_type = new NPCType;
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
|
||||
strncpy(npc_type->name, sep.arg[0], 60);
|
||||
@@ -974,7 +1052,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
|
||||
npc_type->prim_melee_type = 28;
|
||||
npc_type->sec_melee_type = 28;
|
||||
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode3);
|
||||
auto npc = new NPC(npc_type, nullptr, position, FlyMode3);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
|
||||
entity_list.AddNPC(npc);
|
||||
@@ -1029,7 +1107,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version,
|
||||
query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
"VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %i, %i, %i)",
|
||||
npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(),
|
||||
spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(),
|
||||
spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(),
|
||||
@@ -1043,7 +1121,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version,
|
||||
query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, "
|
||||
"texture, helmtexture, size, loottable_id, merchant_id, face, "
|
||||
"runspeed, prim_melee_type, sec_melee_type) "
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)",
|
||||
"VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %i, %i, %i)",
|
||||
tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(),
|
||||
spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(),
|
||||
spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
|
||||
@@ -1061,6 +1139,9 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version,
|
||||
}
|
||||
uint32 spawngroupid = results.LastInsertedID();
|
||||
|
||||
spawn->SetSp2(spawngroupid);
|
||||
spawn->SetNPCTypeID(npc_type_id);
|
||||
|
||||
query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) "
|
||||
"VALUES('%s', %u, %f, %f, %f, %i, %f, %i)",
|
||||
zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, spawn->GetHeading(),
|
||||
@@ -1293,7 +1374,7 @@ uint32 ZoneDatabase::NPCSpawnDB(uint8 command, const char* zone, uint32 zone_ver
|
||||
|
||||
int32 NPC::GetEquipmentMaterial(uint8 material_slot) const
|
||||
{
|
||||
if (material_slot >= _MaterialCount)
|
||||
if (material_slot >= EQEmu::textures::TextureCount)
|
||||
return 0;
|
||||
|
||||
int16 invslot = Inventory::CalcSlotFromMaterial(material_slot);
|
||||
@@ -1304,13 +1385,23 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const
|
||||
{
|
||||
switch(material_slot)
|
||||
{
|
||||
case MaterialHead:
|
||||
case EQEmu::textures::TextureHead:
|
||||
return helmtexture;
|
||||
case MaterialChest:
|
||||
case EQEmu::textures::TextureChest:
|
||||
return texture;
|
||||
case MaterialPrimary:
|
||||
case EQEmu::textures::TextureArms:
|
||||
return armtexture;
|
||||
case EQEmu::textures::TextureWrist:
|
||||
return bracertexture;
|
||||
case EQEmu::textures::TextureHands:
|
||||
return handtexture;
|
||||
case EQEmu::textures::TextureLegs:
|
||||
return legtexture;
|
||||
case EQEmu::textures::TextureFeet:
|
||||
return feettexture;
|
||||
case EQEmu::textures::TexturePrimary:
|
||||
return d_melee_texture1;
|
||||
case MaterialSecondary:
|
||||
case EQEmu::textures::TextureSecondary:
|
||||
return d_melee_texture2;
|
||||
default:
|
||||
//they have nothing in the slot, and its not a special slot... they get nothing.
|
||||
@@ -1336,13 +1427,13 @@ uint32 NPC::GetMaxDamage(uint8 tlevel)
|
||||
return dmg;
|
||||
}
|
||||
|
||||
void NPC::PickPocket(Client* thief) {
|
||||
void NPC::PickPocket(Client* thief)
|
||||
{
|
||||
thief->CheckIncreaseSkill(EQEmu::skills::SkillPickPockets, nullptr, 5);
|
||||
|
||||
thief->CheckIncreaseSkill(SkillPickPockets, nullptr, 5);
|
||||
|
||||
//make sure were allowed to targte them:
|
||||
int olevel = GetLevel();
|
||||
if(olevel > (thief->GetLevel() + THIEF_PICKPOCKET_OVER)) {
|
||||
//make sure were allowed to target them:
|
||||
int over_level = GetLevel();
|
||||
if(over_level > (thief->GetLevel() + THIEF_PICKPOCKET_OVER)) {
|
||||
thief->Message(13, "You are too inexperienced to pick pocket this target");
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketFailed);
|
||||
//should we check aggro
|
||||
@@ -1357,151 +1448,110 @@ void NPC::PickPocket(Client* thief) {
|
||||
return;
|
||||
}
|
||||
|
||||
int steal_skill = thief->GetSkill(SkillPickPockets);
|
||||
int stealchance = steal_skill*100/(5*olevel+5);
|
||||
ItemInst* inst = 0;
|
||||
int x = 0;
|
||||
int slot[50];
|
||||
int steal_items[50];
|
||||
int charges[50];
|
||||
int money[4];
|
||||
money[0] = GetPlatinum();
|
||||
money[1] = GetGold();
|
||||
money[2] = GetSilver();
|
||||
money[3] = GetCopper();
|
||||
if (steal_skill < 125)
|
||||
money[0] = 0;
|
||||
if (steal_skill < 60)
|
||||
money[1] = 0;
|
||||
memset(slot,0,50);
|
||||
memset(steal_items,0,50);
|
||||
memset(charges,0,50);
|
||||
//Determine wheter to steal money or an item.
|
||||
bool no_coin = ((money[0] + money[1] + money[2] + money[3]) == 0);
|
||||
bool steal_item = (zone->random.Roll(50) || no_coin);
|
||||
if (steal_item)
|
||||
{
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
for(; cur != end && x < 49; ++cur) {
|
||||
ServerLootItem_Struct* citem = *cur;
|
||||
const Item_Struct* item = database.GetItem(citem->item_id);
|
||||
if (item)
|
||||
{
|
||||
inst = database.CreateItem(item, citem->charges);
|
||||
bool is_arrow = (item->ItemType == ItemTypeArrow) ? true : false;
|
||||
int slot_id = thief->GetInv().FindFreeSlot(false, true, inst->GetItem()->Size, is_arrow);
|
||||
if (/*!Equipped(item->ID) &&*/
|
||||
!item->Magic && item->NoDrop != 0 && !inst->IsType(ItemClassContainer) && slot_id != INVALID_INDEX
|
||||
/*&& steal_skill > item->StealSkill*/ )
|
||||
{
|
||||
slot[x] = slot_id;
|
||||
steal_items[x] = item->ID;
|
||||
if (inst->IsStackable())
|
||||
charges[x] = 1;
|
||||
else
|
||||
charges[x] = citem->charges;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
int steal_skill = thief->GetSkill(EQEmu::skills::SkillPickPockets);
|
||||
int steal_chance = steal_skill * 100 / (5 * over_level + 5);
|
||||
|
||||
// Determine whether to steal money or an item.
|
||||
uint32 money[6] = { 0, ((steal_skill >= 125) ? (GetPlatinum()) : (0)), ((steal_skill >= 60) ? (GetGold()) : (0)), GetSilver(), GetCopper(), 0 };
|
||||
bool has_coin = ((money[PickPocketPlatinum] | money[PickPocketGold] | money[PickPocketSilver] | money[PickPocketCopper]) != 0);
|
||||
bool steal_item = (steal_skill >= steal_chance && (zone->random.Roll(50) || !has_coin));
|
||||
|
||||
// still needs to have FindFreeSlot vs PutItemInInventory issue worked out
|
||||
while (steal_item) {
|
||||
std::vector<std::pair<const EQEmu::ItemBase*, uint16>> loot_selection; // <const ItemBase*, charges>
|
||||
for (auto item_iter : itemlist) {
|
||||
if (!item_iter || !item_iter->item_id)
|
||||
continue;
|
||||
|
||||
auto item_test = database.GetItem(item_iter->item_id);
|
||||
if (item_test->Magic || !item_test->NoDrop || item_test->IsClassBag() || thief->CheckLoreConflict(item_test))
|
||||
continue;
|
||||
|
||||
loot_selection.push_back(std::make_pair(item_test, ((item_test->Stackable) ? (1) : (item_iter->charges))));
|
||||
}
|
||||
if (x > 0)
|
||||
{
|
||||
int random = zone->random.Int(0, x-1);
|
||||
inst = database.CreateItem(steal_items[random], charges[random]);
|
||||
if (inst)
|
||||
{
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
if (item)
|
||||
{
|
||||
if (/*item->StealSkill || */steal_skill >= stealchance)
|
||||
{
|
||||
thief->PutItemInInventory(slot[random], *inst);
|
||||
thief->SendItemPacket(slot[random], inst, ItemPacketTrade);
|
||||
RemoveItem(item->ID);
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketItem, item);
|
||||
}
|
||||
else
|
||||
steal_item = false;
|
||||
}
|
||||
else
|
||||
steal_item = false;
|
||||
}
|
||||
else
|
||||
steal_item = false;
|
||||
}
|
||||
else if (!no_coin)
|
||||
{
|
||||
if (loot_selection.empty()) {
|
||||
steal_item = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
thief->Message(0, "This target's pockets are empty");
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketFailed);
|
||||
}
|
||||
}
|
||||
if (!steal_item) //Steal money
|
||||
{
|
||||
uint32 amt = zone->random.Int(1, (steal_skill/25)+1);
|
||||
int steal_type = 0;
|
||||
if (!money[0])
|
||||
{
|
||||
steal_type = 1;
|
||||
if (!money[1])
|
||||
{
|
||||
steal_type = 2;
|
||||
if (!money[2])
|
||||
{
|
||||
steal_type = 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (zone->random.Roll(stealchance))
|
||||
{
|
||||
switch (steal_type)
|
||||
{
|
||||
case 0:{
|
||||
if (amt > GetPlatinum())
|
||||
amt = GetPlatinum();
|
||||
SetPlatinum(GetPlatinum()-amt);
|
||||
thief->AddMoneyToPP(0,0,0,amt,false);
|
||||
thief->SendPickPocketResponse(this, amt, PickPocketPlatinum);
|
||||
break;
|
||||
}
|
||||
case 1:{
|
||||
if (amt > GetGold())
|
||||
amt = GetGold();
|
||||
SetGold(GetGold()-amt);
|
||||
thief->AddMoneyToPP(0,0,amt,0,false);
|
||||
thief->SendPickPocketResponse(this, amt, PickPocketGold);
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
if (amt > GetSilver())
|
||||
amt = GetSilver();
|
||||
SetSilver(GetSilver()-amt);
|
||||
thief->AddMoneyToPP(0,amt,0,0,false);
|
||||
thief->SendPickPocketResponse(this, amt, PickPocketSilver);
|
||||
break;
|
||||
}
|
||||
case 3:{
|
||||
if (amt > GetCopper())
|
||||
amt = GetCopper();
|
||||
SetCopper(GetCopper()-amt);
|
||||
thief->AddMoneyToPP(amt,0,0,0,false);
|
||||
thief->SendPickPocketResponse(this, amt, PickPocketCopper);
|
||||
break;
|
||||
}
|
||||
int random = zone->random.Int(0, (loot_selection.size() - 1));
|
||||
uint16 slot_id = thief->GetInv().FindFreeSlot(false, true, (loot_selection[random].first->Size), (loot_selection[random].first->ItemType == EQEmu::item::ItemTypeArrow));
|
||||
if (slot_id == INVALID_INDEX) {
|
||||
steal_item = false;
|
||||
break;
|
||||
}
|
||||
|
||||
auto item_inst = database.CreateItem(loot_selection[random].first, loot_selection[random].second);
|
||||
if (item_inst == nullptr) {
|
||||
steal_item = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Successful item pickpocket
|
||||
if (item_inst->IsStackable() && RuleB(Character, UseStackablePickPocketing)) {
|
||||
if (!thief->TryStacking(item_inst, ItemPacketTrade, false, false)) {
|
||||
thief->PutItemInInventory(slot_id, *item_inst);
|
||||
thief->SendItemPacket(slot_id, item_inst, ItemPacketTrade);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketFailed);
|
||||
else {
|
||||
thief->PutItemInInventory(slot_id, *item_inst);
|
||||
thief->SendItemPacket(slot_id, item_inst, ItemPacketTrade);
|
||||
}
|
||||
RemoveItem(item_inst->GetID());
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketItem, item_inst->GetItem());
|
||||
|
||||
return;
|
||||
}
|
||||
safe_delete(inst);
|
||||
|
||||
while (!steal_item && has_coin) {
|
||||
uint32 coin_amount = zone->random.Int(1, (steal_skill / 25) + 1);
|
||||
|
||||
int coin_type = PickPocketPlatinum;
|
||||
while (coin_type <= PickPocketCopper) {
|
||||
if (money[coin_type]) {
|
||||
if (coin_amount > money[coin_type])
|
||||
coin_amount = money[coin_type];
|
||||
break;
|
||||
}
|
||||
++coin_type;
|
||||
}
|
||||
if (coin_type > PickPocketCopper)
|
||||
break;
|
||||
|
||||
memset(money, 0, (sizeof(int) * 6));
|
||||
money[coin_type] = coin_amount;
|
||||
|
||||
if (zone->random.Roll(steal_chance)) { // Successful coin pickpocket
|
||||
switch (coin_type) {
|
||||
case PickPocketPlatinum:
|
||||
SetPlatinum(GetPlatinum() - coin_amount);
|
||||
break;
|
||||
case PickPocketGold:
|
||||
SetGold(GetGold() - coin_amount);
|
||||
break;
|
||||
case PickPocketSilver:
|
||||
SetSilver(GetSilver() - coin_amount);
|
||||
break;
|
||||
case PickPocketCopper:
|
||||
SetCopper(GetCopper() - coin_amount);
|
||||
break;
|
||||
default: // has_coin..but, doesn't have coin?
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
thief->AddMoneyToPP(money[PickPocketCopper], money[PickPocketSilver], money[PickPocketGold], money[PickPocketPlatinum], false);
|
||||
thief->SendPickPocketResponse(this, coin_amount, coin_type);
|
||||
return;
|
||||
}
|
||||
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
thief->Message(0, "This target's pockets are empty");
|
||||
thief->SendPickPocketResponse(this, 0, PickPocketFailed);
|
||||
}
|
||||
|
||||
void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool remove) {
|
||||
@@ -1839,7 +1889,7 @@ void NPC::PetOnSpawn(NewSpawn_Struct* ns)
|
||||
if(swarmOwner->IsClient())
|
||||
{
|
||||
SetPetOwnerClient(true); //Simple flag to determine if pet belongs to a client
|
||||
SetAllowBeneficial(1);//Allow temp pets to receive buffs and heals if owner is client.
|
||||
SetAllowBeneficial(true);//Allow temp pets to receive buffs and heals if owner is client.
|
||||
//This will allow CLIENT swarm pets NOT to be targeted with F8.
|
||||
ns->spawn.targetable_with_hotkey = 0;
|
||||
no_target_hotkey = 1;
|
||||
@@ -1913,12 +1963,20 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
|
||||
else if(id == "cr") { CR = atoi(val.c_str()); return; }
|
||||
else if(id == "pr") { PR = atoi(val.c_str()); return; }
|
||||
else if(id == "dr") { DR = atoi(val.c_str()); return; }
|
||||
else if(id == "PhR") { PhR = atoi(val.c_str()); return; }
|
||||
else if(id == "runspeed") { runspeed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
||||
else if(id == "phr") { PhR = atoi(val.c_str()); return; }
|
||||
else if(id == "runspeed") {
|
||||
runspeed = (float)atof(val.c_str());
|
||||
base_runspeed = (int)((float)runspeed * 40.0f);
|
||||
base_walkspeed = base_runspeed * 100 / 265;
|
||||
walkspeed = ((float)base_walkspeed) * 0.025f;
|
||||
base_fearspeed = base_runspeed * 100 / 127;
|
||||
fearspeed = ((float)base_fearspeed) * 0.025f;
|
||||
CalcBonuses(); return;
|
||||
}
|
||||
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
|
||||
else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; }
|
||||
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
||||
else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; }
|
||||
else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; }
|
||||
else if(id == "atk") { ATK = atoi(val.c_str()); return; }
|
||||
else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; }
|
||||
else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; }
|
||||
@@ -1939,6 +1997,8 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
|
||||
else if(id == "loottable_id") { loottable_id = atof(val.c_str()); return; }
|
||||
else if(id == "healscale") { healscale = atof(val.c_str()); return; }
|
||||
else if(id == "spellscale") { spellscale = atof(val.c_str()); return; }
|
||||
else if(id == "npc_spells_id") { AI_AddNPCSpells(atoi(val.c_str())); return; }
|
||||
else if(id == "npc_spells_effects_id") { AI_AddNPCSpellsEffects(atoi(val.c_str())); CalcBonuses(); return; }
|
||||
}
|
||||
|
||||
void NPC::LevelScale() {
|
||||
@@ -1947,44 +2007,90 @@ void NPC::LevelScale() {
|
||||
|
||||
float scaling = (((random_level / (float)level) - 1) * (scalerate / 100.0f));
|
||||
|
||||
// Compensate for scale rates at low levels so they don't add too much
|
||||
uint8 scale_adjust = 1;
|
||||
if(level > 0 && level <= 5)
|
||||
scale_adjust = 10;
|
||||
if(level > 5 && level <= 10)
|
||||
scale_adjust = 5;
|
||||
if(level > 10 && level <= 15)
|
||||
scale_adjust = 3;
|
||||
if(level > 15 && level <= 25)
|
||||
scale_adjust = 2;
|
||||
if (RuleB(NPC, NewLevelScaling)) {
|
||||
if (scalerate == 0 || maxlevel <= 25) {
|
||||
// pre-pop seems to scale by 20 HP increments while newer by 100
|
||||
// We also don't want 100 increments on newer noobie zones, check level
|
||||
if (zone->GetZoneID() < 200 || level < 48) {
|
||||
max_hp += (random_level - level) * 20;
|
||||
base_hp += (random_level - level) * 20;
|
||||
} else {
|
||||
max_hp += (random_level - level) * 100;
|
||||
base_hp += (random_level - level) * 100;
|
||||
}
|
||||
|
||||
base_hp += (int)(base_hp * scaling);
|
||||
max_hp += (int)(max_hp * scaling);
|
||||
cur_hp = max_hp;
|
||||
STR += (int)(STR * scaling / scale_adjust);
|
||||
STA += (int)(STA * scaling / scale_adjust);
|
||||
AGI += (int)(AGI * scaling / scale_adjust);
|
||||
DEX += (int)(DEX * scaling / scale_adjust);
|
||||
INT += (int)(INT * scaling / scale_adjust);
|
||||
WIS += (int)(WIS * scaling / scale_adjust);
|
||||
CHA += (int)(CHA * scaling / scale_adjust);
|
||||
if (MR)
|
||||
MR += (int)(MR * scaling / scale_adjust);
|
||||
if (CR)
|
||||
CR += (int)(CR * scaling / scale_adjust);
|
||||
if (DR)
|
||||
DR += (int)(DR * scaling / scale_adjust);
|
||||
if (FR)
|
||||
FR += (int)(FR * scaling / scale_adjust);
|
||||
if (PR)
|
||||
PR += (int)(PR * scaling / scale_adjust);
|
||||
cur_hp = max_hp;
|
||||
max_dmg += (random_level - level) * 2;
|
||||
} else {
|
||||
uint8 scale_adjust = 1;
|
||||
|
||||
base_hp += (int)(base_hp * scaling);
|
||||
max_hp += (int)(max_hp * scaling);
|
||||
cur_hp = max_hp;
|
||||
|
||||
if (max_dmg) {
|
||||
max_dmg += (int)(max_dmg * scaling / scale_adjust);
|
||||
min_dmg += (int)(min_dmg * scaling / scale_adjust);
|
||||
}
|
||||
|
||||
STR += (int)(STR * scaling / scale_adjust);
|
||||
STA += (int)(STA * scaling / scale_adjust);
|
||||
AGI += (int)(AGI * scaling / scale_adjust);
|
||||
DEX += (int)(DEX * scaling / scale_adjust);
|
||||
INT += (int)(INT * scaling / scale_adjust);
|
||||
WIS += (int)(WIS * scaling / scale_adjust);
|
||||
CHA += (int)(CHA * scaling / scale_adjust);
|
||||
if (MR)
|
||||
MR += (int)(MR * scaling / scale_adjust);
|
||||
if (CR)
|
||||
CR += (int)(CR * scaling / scale_adjust);
|
||||
if (DR)
|
||||
DR += (int)(DR * scaling / scale_adjust);
|
||||
if (FR)
|
||||
FR += (int)(FR * scaling / scale_adjust);
|
||||
if (PR)
|
||||
PR += (int)(PR * scaling / scale_adjust);
|
||||
}
|
||||
} else {
|
||||
// Compensate for scale rates at low levels so they don't add too much
|
||||
uint8 scale_adjust = 1;
|
||||
if(level > 0 && level <= 5)
|
||||
scale_adjust = 10;
|
||||
if(level > 5 && level <= 10)
|
||||
scale_adjust = 5;
|
||||
if(level > 10 && level <= 15)
|
||||
scale_adjust = 3;
|
||||
if(level > 15 && level <= 25)
|
||||
scale_adjust = 2;
|
||||
|
||||
base_hp += (int)(base_hp * scaling);
|
||||
max_hp += (int)(max_hp * scaling);
|
||||
cur_hp = max_hp;
|
||||
STR += (int)(STR * scaling / scale_adjust);
|
||||
STA += (int)(STA * scaling / scale_adjust);
|
||||
AGI += (int)(AGI * scaling / scale_adjust);
|
||||
DEX += (int)(DEX * scaling / scale_adjust);
|
||||
INT += (int)(INT * scaling / scale_adjust);
|
||||
WIS += (int)(WIS * scaling / scale_adjust);
|
||||
CHA += (int)(CHA * scaling / scale_adjust);
|
||||
if (MR)
|
||||
MR += (int)(MR * scaling / scale_adjust);
|
||||
if (CR)
|
||||
CR += (int)(CR * scaling / scale_adjust);
|
||||
if (DR)
|
||||
DR += (int)(DR * scaling / scale_adjust);
|
||||
if (FR)
|
||||
FR += (int)(FR * scaling / scale_adjust);
|
||||
if (PR)
|
||||
PR += (int)(PR * scaling / scale_adjust);
|
||||
|
||||
if (max_dmg)
|
||||
{
|
||||
max_dmg += (int)(max_dmg * scaling / scale_adjust);
|
||||
min_dmg += (int)(min_dmg * scaling / scale_adjust);
|
||||
}
|
||||
|
||||
if (max_dmg)
|
||||
{
|
||||
max_dmg += (int)(max_dmg * scaling / scale_adjust);
|
||||
min_dmg += (int)(min_dmg * scaling / scale_adjust);
|
||||
}
|
||||
|
||||
level = random_level;
|
||||
|
||||
return;
|
||||
@@ -2258,8 +2364,6 @@ bool NPC::CanTalk()
|
||||
0,0,420,0,0,0,0,425,0,0,0,0,0,0,0,433,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,458,0,0,0,0,0,0,0,0,467,0,0,470,0,0,473};
|
||||
|
||||
int talk_check = TalkRace[GetRace() - 1];
|
||||
|
||||
if (TalkRace[GetRace() - 1] > 0)
|
||||
return true;
|
||||
|
||||
@@ -2405,10 +2509,10 @@ void NPC::DoQuestPause(Mob *other) {
|
||||
|
||||
}
|
||||
|
||||
void NPC::ChangeLastName(const char* in_lastname)
|
||||
void NPC::ChangeLastName(const char* in_lastname)
|
||||
{
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GMLastName, sizeof(GMLastName_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_GMLastName, sizeof(GMLastName_Struct));
|
||||
GMLastName_Struct* gmn = (GMLastName_Struct*)outapp->pBuffer;
|
||||
strcpy(gmn->name, GetName());
|
||||
strcpy(gmn->gmname, GetName());
|
||||
@@ -2455,9 +2559,9 @@ void NPC::DepopSwarmPets()
|
||||
}
|
||||
|
||||
if (IsPet() && GetPetType() == petTargetLock && GetPetTargetLockID()){
|
||||
|
||||
|
||||
Mob *targMob = entity_list.GetMob(GetPetTargetLockID());
|
||||
|
||||
|
||||
if(!targMob || (targMob && targMob->IsCorpse())){
|
||||
Kill();
|
||||
return;
|
||||
|
||||
+22
-13
@@ -90,12 +90,17 @@ class Client;
|
||||
class Group;
|
||||
class Raid;
|
||||
class Spawn2;
|
||||
struct Item_Struct;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemBase;
|
||||
}
|
||||
|
||||
class NPC : public Mob
|
||||
{
|
||||
public:
|
||||
static NPC* SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client = nullptr);
|
||||
static bool SpawnZoneController();
|
||||
static int8 GetAILevel(bool iForceReRead = false);
|
||||
|
||||
NPC(const NPCType* data, Spawn2* respawn, const glm::vec4& position, int iflymode, bool IsCorpse = false);
|
||||
@@ -103,10 +108,10 @@ public:
|
||||
virtual ~NPC();
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
|
||||
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
@@ -119,6 +124,7 @@ public:
|
||||
virtual void AI_Start(uint32 iMoveDelay = 0);
|
||||
virtual void AI_Stop();
|
||||
void AI_DoMovement();
|
||||
void AI_SetupNextWaypoint();
|
||||
bool AI_AddNPCSpells(uint32 iDBSpellsID);
|
||||
bool AI_AddNPCSpellsEffects(uint32 iDBSpellsEffectsID);
|
||||
virtual bool AI_EngagedCastCheck();
|
||||
@@ -136,7 +142,7 @@ public:
|
||||
void CalcNPCDamage();
|
||||
|
||||
virtual void SetTarget(Mob* mob);
|
||||
virtual uint16 GetSkill(SkillUseTypes skill_num) const { if (skill_num <= HIGHEST_SKILL) { return skills[skill_num]; } return 0; }
|
||||
virtual uint16 GetSkill(EQEmu::skills::SkillType skill_num) const { if (skill_num <= EQEmu::skills::HIGHEST_SKILL) { return skills[skill_num]; } return 0; }
|
||||
|
||||
void CalcItemBonuses(StatBonuses *newbon);
|
||||
virtual void CalcBonuses();
|
||||
@@ -155,7 +161,7 @@ public:
|
||||
virtual void RangedAttack(Mob* other);
|
||||
virtual void ThrowingAttack(Mob* other) { }
|
||||
int32 GetNumberOfAttacks() const { return attack_count; }
|
||||
void DoRangedAttackDmg(Mob* other, bool Launch=true, int16 damage_mod=0, int16 chance_mod=0, SkillUseTypes skill=SkillArchery, float speed=4.0f, const char *IDFile = nullptr);
|
||||
void DoRangedAttackDmg(Mob* other, bool Launch = true, int16 damage_mod = 0, int16 chance_mod = 0, EQEmu::skills::SkillType skill = EQEmu::skills::SkillArchery, float speed = 4.0f, const char *IDFile = nullptr);
|
||||
|
||||
bool DatabaseCastAccepted(int spell_id);
|
||||
bool IsFactionListAlly(uint32 other_faction);
|
||||
@@ -163,7 +169,7 @@ public:
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
|
||||
|
||||
void GoToBind(uint8 bindnum = 0) { GMMove(m_SpawnPoint.x, m_SpawnPoint.y, m_SpawnPoint.z, m_SpawnPoint.w); }
|
||||
void Gate();
|
||||
void Gate(uint8 bindnum = 0);
|
||||
|
||||
void GetPetState(SpellBuff_Struct *buffs, uint32 *items, char *name);
|
||||
void SetPetState(SpellBuff_Struct *buffs, uint32 *items);
|
||||
@@ -172,7 +178,7 @@ public:
|
||||
virtual void SpellProcess();
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
|
||||
void AddItem(const Item_Struct* item, uint16 charges, bool equipitem = true);
|
||||
void AddItem(const EQEmu::ItemBase* item, uint16 charges, bool equipitem = true);
|
||||
void AddItem(uint32 itemid, uint16 charges, bool equipitem = true);
|
||||
void AddLootTable();
|
||||
void AddLootTable(uint32 ldid);
|
||||
@@ -264,7 +270,7 @@ public:
|
||||
bool IsTaunting() const { return taunting; }
|
||||
void PickPocket(Client* thief);
|
||||
void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); }
|
||||
void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
|
||||
void AddLootDrop(const EQEmu::ItemBase*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
|
||||
virtual void DoClassAttacks(Mob *target);
|
||||
void CheckSignal();
|
||||
inline bool IsNotTargetableWithHotkey() const { return no_target_hotkey; }
|
||||
@@ -397,15 +403,17 @@ public:
|
||||
void SetMerchantProbability(uint8 amt) { probability = amt; }
|
||||
uint8 GetMerchantProbability() { return probability; }
|
||||
void mod_prespawn(Spawn2 *sp);
|
||||
int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other);
|
||||
int mod_npc_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const EQEmu::ItemBase* weapon, Mob* other);
|
||||
void mod_npc_killed_merit(Mob* c);
|
||||
void mod_npc_killed(Mob* oos);
|
||||
void AISpellsList(Client *c);
|
||||
uint16 GetInnateProcSpellID() const { return innate_proc_spell_id; }
|
||||
|
||||
uint32 GetHeroForgeModel() const { return herosforgemodel; }
|
||||
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
|
||||
|
||||
bool IsRaidTarget() const { return raid_target; };
|
||||
void ResetHPUpdateTimer() { sendhpupdate_timer.Start(); }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -447,6 +455,7 @@ protected:
|
||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
AISpellsVar_Struct AISpellVar;
|
||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
uint16 innate_proc_spell_id;
|
||||
|
||||
uint32 npc_spells_effects_id;
|
||||
std::vector<AISpellsEffects_Struct> AIspellsEffects;
|
||||
@@ -490,9 +499,9 @@ protected:
|
||||
uint32 roambox_delay;
|
||||
uint32 roambox_min_delay;
|
||||
|
||||
uint16 skills[HIGHEST_SKILL+1];
|
||||
uint16 skills[EQEmu::skills::HIGHEST_SKILL + 1];
|
||||
|
||||
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
|
||||
uint32 equipment[EQEmu::legacy::EQUIPMENT_SIZE]; //this is an array of item IDs
|
||||
|
||||
uint32 herosforgemodel; //this is the Hero Forge Armor Model (i.e 63 or 84 or 203)
|
||||
uint16 d_melee_texture1; //this is an item Material value
|
||||
|
||||
+82
-61
@@ -117,7 +117,7 @@ Object::Object(Client* client, const ItemInst* inst)
|
||||
m_data.heading = client->GetHeading();
|
||||
m_data.x = client->GetX();
|
||||
m_data.y = client->GetY();
|
||||
if (client->GetClientVersion() >= ClientVersion::RoF2)
|
||||
if (client->ClientVersion() >= EQEmu::versions::ClientVersion::RoF2)
|
||||
{
|
||||
// RoF2 places items at player's Z, which is 0.625 of their height.
|
||||
m_data.z = client->GetZ() - (client->GetSize() * 0.625f);
|
||||
@@ -138,7 +138,7 @@ Object::Object(Client* client, const ItemInst* inst)
|
||||
|
||||
// Set object name
|
||||
if (inst) {
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const EQEmu::ItemBase* item = inst->GetItem();
|
||||
if (item && item->IDFile) {
|
||||
if (strlen(item->IDFile) == 0) {
|
||||
strcpy(m_data.object_name, DEFAULT_OBJECT_NAME);
|
||||
@@ -194,7 +194,7 @@ Object::Object(const ItemInst *inst, float x, float y, float z, float heading, u
|
||||
|
||||
// Set object name
|
||||
if (inst) {
|
||||
const Item_Struct* item = inst->GetItem();
|
||||
const EQEmu::ItemBase* item = inst->GetItem();
|
||||
if (item && item->IDFile) {
|
||||
if (strlen(item->IDFile) == 0) {
|
||||
strcpy(m_data.object_name, DEFAULT_OBJECT_NAME);
|
||||
@@ -324,7 +324,7 @@ void Object::Delete(bool reset_state)
|
||||
}
|
||||
|
||||
const ItemInst* Object::GetItem(uint8 index) {
|
||||
if (index < EmuConstants::MAP_WORLD_SIZE) {
|
||||
if (index < EQEmu::legacy::TYPE_WORLD_SIZE) {
|
||||
return m_inst->GetItem(index);
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ void Object::PutItem(uint8 index, const ItemInst* inst)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_inst && m_inst->IsType(ItemClassContainer)) {
|
||||
if (m_inst && m_inst->IsType(EQEmu::item::ItemClassBag)) {
|
||||
if (inst) {
|
||||
m_inst->PutItem(index, *inst);
|
||||
}
|
||||
@@ -362,7 +362,7 @@ void Object::Close() {
|
||||
ItemInst* container = this->m_inst;
|
||||
if(container != nullptr)
|
||||
{
|
||||
for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++)
|
||||
for (uint8 i = SUB_INDEX_BEGIN; i < EQEmu::legacy::ITEM_CONTAINER_SIZE; i++)
|
||||
{
|
||||
ItemInst* inst = container->PopItem(i);
|
||||
if(inst != nullptr)
|
||||
@@ -380,7 +380,7 @@ void Object::Close() {
|
||||
// Remove item from container
|
||||
void Object::DeleteItem(uint8 index)
|
||||
{
|
||||
if (m_inst && m_inst->IsType(ItemClassContainer)) {
|
||||
if (m_inst && m_inst->IsType(EQEmu::item::ItemClassBag)) {
|
||||
m_inst->DeleteItem(index);
|
||||
|
||||
// This is _highly_ inefficient, but for now it will work: Save entire object to database
|
||||
@@ -393,7 +393,7 @@ ItemInst* Object::PopItem(uint8 index)
|
||||
{
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
if (m_inst && m_inst->IsType(ItemClassContainer)) {
|
||||
if (m_inst && m_inst->IsType(EQEmu::item::ItemClassBag)) {
|
||||
inst = m_inst->PopItem(index);
|
||||
|
||||
// This is _highly_ inefficient, but for now it will work: Save entire object to database
|
||||
@@ -425,7 +425,7 @@ void Object::CreateDeSpawnPacket(EQApplicationPacket* app)
|
||||
bool Object::Process(){
|
||||
if(m_type == OT_DROPPEDITEM && decay_timer.Enabled() && decay_timer.Check()) {
|
||||
// Send click to all clients (removes entity on client)
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClickObject, sizeof(ClickObject_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_ClickObject, sizeof(ClickObject_Struct));
|
||||
ClickObject_Struct* click_object = (ClickObject_Struct*)outapp->pBuffer;
|
||||
click_object->drop_id = GetID();
|
||||
entity_list.QueueClients(nullptr, outapp, false);
|
||||
@@ -485,14 +485,29 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
buf[9] = '\0';
|
||||
std::vector<EQEmu::Any> args;
|
||||
args.push_back(m_inst);
|
||||
parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, 0, &args);
|
||||
if(parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, this->GetID(), &args))
|
||||
{
|
||||
auto outapp = new EQApplicationPacket(OP_ClickObject, sizeof(ClickObject_Struct));
|
||||
memcpy(outapp->pBuffer, click_object, sizeof(ClickObject_Struct));
|
||||
ClickObject_Struct* co = (ClickObject_Struct*)outapp->pBuffer;
|
||||
co->drop_id = 0;
|
||||
entity_list.QueueClients(nullptr, outapp, false);
|
||||
safe_delete(outapp);
|
||||
|
||||
// No longer using a tradeskill object
|
||||
sender->SetTradeskillObject(nullptr);
|
||||
user = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Transfer item to client
|
||||
sender->PutItemInInventory(MainCursor, *m_inst, false);
|
||||
sender->SendItemPacket(MainCursor, m_inst, ItemPacketTrade);
|
||||
sender->PutItemInInventory(EQEmu::legacy::SlotCursor, *m_inst, false);
|
||||
sender->SendItemPacket(EQEmu::legacy::SlotCursor, m_inst, ItemPacketTrade);
|
||||
|
||||
if(cursordelete) // delete the item if it's a duplicate lore. We have to do this because the client expects the item packet
|
||||
sender->DeleteItemInInventory(MainCursor);
|
||||
sender->DeleteItemInInventory(EQEmu::legacy::SlotCursor);
|
||||
|
||||
if(!m_ground_spawn)
|
||||
safe_delete(m_inst);
|
||||
@@ -503,7 +518,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
}
|
||||
|
||||
// Send click to all clients (removes entity on client)
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClickObject, sizeof(ClickObject_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_ClickObject, sizeof(ClickObject_Struct));
|
||||
memcpy(outapp->pBuffer, click_object, sizeof(ClickObject_Struct));
|
||||
entity_list.QueueClients(nullptr, outapp, false);
|
||||
safe_delete(outapp);
|
||||
@@ -514,24 +529,30 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
entity_list.RemoveEntity(this->GetID());
|
||||
} else {
|
||||
// Tradeskill item
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ClickObjectAction, sizeof(ClickObjectAction_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_ClickObjectAction, sizeof(ClickObjectAction_Struct));
|
||||
ClickObjectAction_Struct* coa = (ClickObjectAction_Struct*)outapp->pBuffer;
|
||||
|
||||
//TODO: there is prolly a better way to do this.
|
||||
//if this is not the main user, send them a close and a message
|
||||
if(user == nullptr || user == sender)
|
||||
coa->open = 0x01;
|
||||
else {
|
||||
coa->open = 0x00;
|
||||
//sender->Message(13, "Somebody is allready using that container.");
|
||||
}
|
||||
m_inuse = true;
|
||||
coa->type = m_type;
|
||||
coa->unknown16 = 0x0a;
|
||||
m_inuse = true;
|
||||
coa->type = m_type;
|
||||
coa->unknown16 = 0x0a;
|
||||
|
||||
coa->drop_id = click_object->drop_id;
|
||||
coa->player_id = click_object->player_id;
|
||||
coa->icon = m_icon;
|
||||
coa->drop_id = click_object->drop_id;
|
||||
coa->player_id = click_object->player_id;
|
||||
coa->icon = m_icon;
|
||||
|
||||
//if this is not the main user, send them a close and a message
|
||||
if (user == nullptr || user == sender) {
|
||||
coa->open = 0x01;
|
||||
}
|
||||
else {
|
||||
coa->open = 0x00;
|
||||
|
||||
if (sender->ClientVersion() >= EQEmu::versions::ClientVersion::RoF) {
|
||||
coa->drop_id = 0xFFFFFFFF;
|
||||
sender->Message(0, "Someone else is using that. Try again later.");
|
||||
}
|
||||
}
|
||||
|
||||
if(sender->IsLooting())
|
||||
{
|
||||
@@ -553,16 +574,16 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
|
||||
// Send items inside of container
|
||||
|
||||
if (m_inst && m_inst->IsType(ItemClassContainer)) {
|
||||
if (m_inst && m_inst->IsType(EQEmu::item::ItemClassBag)) {
|
||||
|
||||
//Clear out no-drop and no-rent items first if different player opens it
|
||||
if(user != last_user)
|
||||
m_inst->ClearByFlags(byFlagSet, byFlagSet);
|
||||
|
||||
EQApplicationPacket* outapp=new EQApplicationPacket(OP_ClientReady,0);
|
||||
auto outapp = new EQApplicationPacket(OP_ClientReady, 0);
|
||||
sender->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
|
||||
for (uint8 i = SUB_INDEX_BEGIN; i < EQEmu::legacy::ITEM_CONTAINER_SIZE; i++) {
|
||||
const ItemInst* inst = m_inst->GetItem(i);
|
||||
if (inst) {
|
||||
//sender->GetInv().PutItem(i+4000,inst);
|
||||
@@ -589,7 +610,7 @@ uint32 ZoneDatabase::AddObject(uint32 type, uint32 icon, const Object_Struct& ob
|
||||
|
||||
// SQL Escape object_name
|
||||
uint32 len = strlen(object.object_name) * 2 + 1;
|
||||
char* object_name = new char[len];
|
||||
auto object_name = new char[len];
|
||||
DoEscapeString(object_name, object.object_name, strlen(object.object_name));
|
||||
|
||||
// Save new record for object
|
||||
@@ -607,7 +628,7 @@ uint32 ZoneDatabase::AddObject(uint32 type, uint32 icon, const Object_Struct& ob
|
||||
}
|
||||
|
||||
// Save container contents, if container
|
||||
if (inst && inst->IsType(ItemClassContainer))
|
||||
if (inst && inst->IsType(EQEmu::item::ItemClassBag))
|
||||
SaveWorldContainer(object.zone_id, database_id, inst);
|
||||
|
||||
return database_id;
|
||||
@@ -626,7 +647,7 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec
|
||||
|
||||
// SQL Escape object_name
|
||||
uint32 len = strlen(object.object_name) * 2 + 1;
|
||||
char* object_name = new char[len];
|
||||
auto object_name = new char[len];
|
||||
DoEscapeString(object_name, object.object_name, strlen(object.object_name));
|
||||
|
||||
// Save new record for object
|
||||
@@ -644,7 +665,7 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec
|
||||
}
|
||||
|
||||
// Save container contents, if container
|
||||
if (inst && inst->IsType(ItemClassContainer))
|
||||
if (inst && inst->IsType(EQEmu::item::ItemClassBag))
|
||||
SaveWorldContainer(object.zone_id, id, inst);
|
||||
}
|
||||
|
||||
@@ -733,8 +754,8 @@ void Object::SetX(float pos)
|
||||
{
|
||||
this->m_data.x = pos;
|
||||
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -747,8 +768,8 @@ void Object::SetY(float pos)
|
||||
{
|
||||
this->m_data.y = pos;
|
||||
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -759,7 +780,7 @@ void Object::SetY(float pos)
|
||||
|
||||
void Object::Depop()
|
||||
{
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
entity_list.QueueClients(0, app);
|
||||
safe_delete(app);
|
||||
@@ -768,8 +789,8 @@ void Object::Depop()
|
||||
|
||||
void Object::Repop()
|
||||
{
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -784,8 +805,8 @@ void Object::SetZ(float pos)
|
||||
{
|
||||
this->m_data.z = pos;
|
||||
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -797,8 +818,8 @@ void Object::SetZ(float pos)
|
||||
void Object::SetModelName(const char* modelname)
|
||||
{
|
||||
strn0cpy(m_data.object_name, modelname, sizeof(m_data.object_name)); // 32 is the max for chars in object_name, this should be safe
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -809,9 +830,9 @@ void Object::SetModelName(const char* modelname)
|
||||
|
||||
void Object::SetSize(uint16 size)
|
||||
{
|
||||
m_data.unknown008 = size;
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
m_data.size = size;
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -822,9 +843,9 @@ void Object::SetSize(uint16 size)
|
||||
|
||||
void Object::SetSolidType(uint16 solidtype)
|
||||
{
|
||||
m_data.unknown010 = solidtype;
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
m_data.solidtype = solidtype;
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -835,12 +856,12 @@ void Object::SetSolidType(uint16 solidtype)
|
||||
|
||||
uint16 Object::GetSize()
|
||||
{
|
||||
return m_data.unknown008;
|
||||
return m_data.size;
|
||||
}
|
||||
|
||||
uint16 Object::GetSolidType()
|
||||
{
|
||||
return m_data.unknown010;
|
||||
return m_data.solidtype;
|
||||
}
|
||||
|
||||
const char* Object::GetModelName()
|
||||
@@ -860,7 +881,7 @@ uint32 Object::GetItemID()
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Item_Struct* item = this->m_inst->GetItem();
|
||||
const EQEmu::ItemBase* item = this->m_inst->GetItem();
|
||||
|
||||
if (item == 0)
|
||||
{
|
||||
@@ -919,8 +940,8 @@ void Object::SetLocation(float x, float y, float z)
|
||||
this->m_data.x = x;
|
||||
this->m_data.y = y;
|
||||
this->m_data.z = z;
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -940,8 +961,8 @@ void Object::GetHeading(float* heading)
|
||||
void Object::SetHeading(float heading)
|
||||
{
|
||||
this->m_data.heading = heading;
|
||||
EQApplicationPacket* app = new EQApplicationPacket();
|
||||
EQApplicationPacket* app2 = new EQApplicationPacket();
|
||||
auto app = new EQApplicationPacket();
|
||||
auto app2 = new EQApplicationPacket();
|
||||
this->CreateDeSpawnPacket(app);
|
||||
this->CreateSpawnPacket(app2);
|
||||
entity_list.QueueClients(0, app);
|
||||
@@ -961,7 +982,7 @@ const char* Object::GetEntityVariable(const char *id)
|
||||
if(!id)
|
||||
return nullptr;
|
||||
|
||||
std::map<std::string, std::string>::iterator iter = o_EntityVariables.find(id);
|
||||
auto iter = o_EntityVariables.find(id);
|
||||
if(iter != o_EntityVariables.end())
|
||||
{
|
||||
return iter->second.c_str();
|
||||
@@ -974,7 +995,7 @@ bool Object::EntityVariableExists(const char * id)
|
||||
if(!id)
|
||||
return false;
|
||||
|
||||
std::map<std::string, std::string>::iterator iter = o_EntityVariables.find(id);
|
||||
auto iter = o_EntityVariables.find(id);
|
||||
if(iter != o_EntityVariables.end())
|
||||
{
|
||||
return true;
|
||||
|
||||
+2
-2
@@ -69,7 +69,7 @@ IT10714_ACTORDEF=Augmentation Sealer
|
||||
IT10725_ACTORDEF=Shuriken
|
||||
*/
|
||||
|
||||
#define OT_DROPPEDITEM BagTypeLargeBag
|
||||
#define OT_DROPPEDITEM EQEmu::item::BagTypeLargeBag
|
||||
|
||||
// Icon values:
|
||||
//0x0453 a pie
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
static void HandleAugmentation(Client* user, const AugmentItem_Struct* in_augment, Object *worldo);
|
||||
static void HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac);
|
||||
|
||||
static SkillUseTypes TypeToSkill(uint32 type);
|
||||
static EQEmu::skills::SkillType TypeToSkill(uint32 type);
|
||||
|
||||
// Packet functions
|
||||
void CreateSpawnPacket(EQApplicationPacket* app);
|
||||
|
||||
+2
-2
@@ -1082,11 +1082,11 @@ int32 Client::GenericFocus(uint16 spell_id, uint16 modspellid)
|
||||
switch( spells[modspellid].effectid[i] )
|
||||
{
|
||||
case SE_LimitMaxLevel:
|
||||
if (spell.classes[(GetClass()%16) - 1] > modspell.base[i])
|
||||
if (spell.classes[(GetClass()%17) - 1] > modspell.base[i])
|
||||
return 100;
|
||||
break;
|
||||
case SE_LimitMinLevel:
|
||||
if (spell.classes[(GetClass()%16) - 1] < modspell.base[i])
|
||||
if (spell.classes[(GetClass()%17) - 1] < modspell.base[i])
|
||||
return 100;
|
||||
break;
|
||||
case SE_IncreaseRange:
|
||||
|
||||
+45
-37
@@ -16,7 +16,7 @@
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
//#define PATHDEBUG
|
||||
//#define PATHDEBUG
|
||||
|
||||
extern Zone *zone;
|
||||
|
||||
@@ -52,7 +52,7 @@ PathManager* PathManager::LoadPathFile(const char* ZoneName)
|
||||
|
||||
strlwr(LowerCaseZoneName);
|
||||
|
||||
snprintf(ZonePathFileName, 250, MAP_DIR "/%s.path", LowerCaseZoneName);
|
||||
snprintf(ZonePathFileName, 250, "%s%s.path", Config->MapDir.c_str(), LowerCaseZoneName);
|
||||
|
||||
if((PathFile = fopen(ZonePathFileName, "rb")))
|
||||
{
|
||||
@@ -205,10 +205,10 @@ glm::vec3 PathManager::GetPathNodeCoordinates(int NodeNumber, bool BestZ)
|
||||
}
|
||||
|
||||
std::deque<int> PathManager::FindRoute(int startID, int endID)
|
||||
{
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::None, "FindRoute from node %i to %i", startID, endID);
|
||||
|
||||
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
|
||||
memset(ClosedListFlag, 0, sizeof(int) * Head.PathNodeCount);
|
||||
|
||||
std::deque<AStarNode> OpenList, ClosedList;
|
||||
|
||||
@@ -224,7 +224,7 @@ std::deque<int> PathManager::FindRoute(int startID, int endID)
|
||||
|
||||
OpenList.push_back(AStarEntry);
|
||||
|
||||
while(OpenList.size() > 0)
|
||||
while(!OpenList.empty())
|
||||
{
|
||||
// The OpenList is maintained in sorted order, lowest to highest cost.
|
||||
|
||||
@@ -546,7 +546,7 @@ void PathManager::SpawnPathNodes()
|
||||
|
||||
for(uint32 i = 0; i < Head.PathNodeCount; ++i)
|
||||
{
|
||||
NPCType* npc_type = new NPCType;
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
|
||||
if(PathNodes[i].id < 10)
|
||||
@@ -585,10 +585,10 @@ void PathManager::SpawnPathNodes()
|
||||
|
||||
npc_type->findable = 1;
|
||||
auto position = glm::vec4(PathNodes[i].v.x, PathNodes[i].v.y, PathNodes[i].v.z, 0.0f);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
auto npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ void PathManager::MeshTest()
|
||||
|
||||
std::deque<int> Route = FindRoute(PathNodes[i].id, PathNodes[j].id);
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
{
|
||||
++NoConnections;
|
||||
printf("FindRoute(%i, %i) **** NO ROUTE FOUND ****\n", PathNodes[i].id, PathNodes[j].id);
|
||||
@@ -637,7 +637,7 @@ void PathManager::SimpleMeshTest()
|
||||
{
|
||||
std::deque<int> Route = FindRoute(PathNodes[0].id, PathNodes[j].id);
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
{
|
||||
++NoConnections;
|
||||
printf("FindRoute(%i, %i) **** NO ROUTE FOUND ****\n", PathNodes[0].id, PathNodes[j].id);
|
||||
@@ -665,6 +665,9 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
|
||||
bool SameDestination = (To == PathingDestination);
|
||||
|
||||
if (Speed <= 0) // our speed is 0, we cant move so lets return the dest
|
||||
return To; // this will also avoid the teleports cleanly
|
||||
|
||||
int NextNode;
|
||||
|
||||
if(To == From)
|
||||
@@ -680,7 +683,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::None, "appears to be stuck. Teleporting them to next position.", GetName());
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
{
|
||||
Teleport(To);
|
||||
|
||||
@@ -712,7 +715,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
PathingLastPosition = From;
|
||||
}
|
||||
|
||||
if(Route.size() > 0)
|
||||
if(!Route.empty())
|
||||
{
|
||||
|
||||
// If we are already pathing, and the destination is the same as before ...
|
||||
@@ -787,7 +790,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
WaypointChanged = true;
|
||||
|
||||
// If there are more nodes on the route, return the coords of the next node
|
||||
if(Route.size() > 0)
|
||||
if(!Route.empty())
|
||||
{
|
||||
NextNode = Route.front();
|
||||
|
||||
@@ -796,7 +799,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
// -1 indicates a teleport to the next node
|
||||
Route.pop_front();
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::None, "Missing node after teleport.");
|
||||
return To;
|
||||
@@ -812,7 +815,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
|
||||
Route.pop_front();
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
return To;
|
||||
|
||||
NextNode = Route.front();
|
||||
@@ -962,7 +965,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
|
||||
WaypointChanged = true;
|
||||
|
||||
if(Route.size() > 0)
|
||||
if(!Route.empty())
|
||||
{
|
||||
NextNode = Route.front();
|
||||
|
||||
@@ -971,7 +974,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
// -1 indicates a teleport to the next node
|
||||
Route.pop_front();
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::None, "Missing node after teleport.");
|
||||
return To;
|
||||
@@ -987,7 +990,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
|
||||
Route.pop_front();
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
return To;
|
||||
|
||||
NextNode = Route.front();
|
||||
@@ -1058,7 +1061,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
|
||||
PathingTraversedNodes = 0;
|
||||
|
||||
if(Route.size() == 0)
|
||||
if(Route.empty())
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::None, " No route available, running direct.");
|
||||
|
||||
@@ -1308,7 +1311,7 @@ void Client::SendPathPacket(std::vector<FindPerson_Point> &points) {
|
||||
}
|
||||
|
||||
int len = sizeof(FindPersonResult_Struct) + (points.size()+1) * sizeof(FindPerson_Point);
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_FindPersonReply, len);
|
||||
auto outapp = new EQApplicationPacket(OP_FindPersonReply, len);
|
||||
FindPersonResult_Struct* fpr=(FindPersonResult_Struct*)outapp->pBuffer;
|
||||
|
||||
std::vector<FindPerson_Point>::iterator cur, end;
|
||||
@@ -1478,6 +1481,11 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
{
|
||||
for(uint32 i = 0; i < Head.PathNodeCount; ++i)
|
||||
{
|
||||
if(PathNodes[i].id - new_id > 1) {
|
||||
new_id = PathNodes[i].id - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(PathNodes[i].id > new_id)
|
||||
new_id = PathNodes[i].id;
|
||||
}
|
||||
@@ -1501,7 +1509,7 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
Head.PathNodeCount++;
|
||||
if(Head.PathNodeCount > 1)
|
||||
{
|
||||
PathNode *t_PathNodes = new PathNode[Head.PathNodeCount];
|
||||
auto t_PathNodes = new PathNode[Head.PathNodeCount];
|
||||
for(uint32 x = 0; x < (Head.PathNodeCount - 1); ++x)
|
||||
{
|
||||
t_PathNodes[x].v.x = PathNodes[x].v.x;
|
||||
@@ -1536,7 +1544,7 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
delete[] PathNodes;
|
||||
PathNodes = t_PathNodes;
|
||||
|
||||
NPCType* npc_type = new NPCType;
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
if(new_id < 10)
|
||||
sprintf(npc_type->name, "%s", DigitToWord(new_id));
|
||||
@@ -1573,13 +1581,13 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
npc_type->findable = 1;
|
||||
|
||||
auto position = glm::vec4(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
auto npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
|
||||
safe_delete_array(ClosedListFlag);
|
||||
ClosedListFlag = new int[Head.PathNodeCount];
|
||||
return new_id;
|
||||
safe_delete_array(ClosedListFlag);
|
||||
ClosedListFlag = new int[Head.PathNodeCount];
|
||||
return new_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1597,7 +1605,7 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
PathNodes[0].Neighbours[n].Teleport = new_node.Neighbours[n].Teleport;
|
||||
}
|
||||
|
||||
NPCType* npc_type = new NPCType;
|
||||
auto npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
if(new_id < 10)
|
||||
sprintf(npc_type->name, "%s", DigitToWord(new_id));
|
||||
@@ -1634,13 +1642,13 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
||||
npc_type->findable = 1;
|
||||
|
||||
auto position = glm::vec4(new_node.v.x, new_node.v.y, new_node.v.z, 0.0f);
|
||||
NPC* npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
auto npc = new NPC(npc_type, nullptr, position, FlyMode1);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
entity_list.AddNPC(npc, true, true);
|
||||
|
||||
ClosedListFlag = new int[Head.PathNodeCount];
|
||||
ClosedListFlag = new int[Head.PathNodeCount];
|
||||
|
||||
return new_id;
|
||||
return new_id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1676,7 +1684,7 @@ bool PathManager::DeleteNode(int32 id)
|
||||
|
||||
if(Head.PathNodeCount > 1)
|
||||
{
|
||||
PathNode *t_PathNodes = new PathNode[Head.PathNodeCount-1];
|
||||
auto t_PathNodes = new PathNode[Head.PathNodeCount - 1];
|
||||
uint32 index = 0;
|
||||
for(uint32 x = 0; x < Head.PathNodeCount; x++)
|
||||
{
|
||||
@@ -2225,7 +2233,7 @@ void PathManager::SortNodes()
|
||||
sorted_vals.push_back(tmp);
|
||||
}
|
||||
|
||||
PathNode *t_PathNodes = new PathNode[Head.PathNodeCount];
|
||||
auto t_PathNodes = new PathNode[Head.PathNodeCount];
|
||||
memcpy(t_PathNodes, PathNodes, sizeof(PathNode)*Head.PathNodeCount);
|
||||
for(uint32 i = 0; i < Head.PathNodeCount; ++i)
|
||||
{
|
||||
|
||||
+3
-1
@@ -2,9 +2,11 @@
|
||||
#define PATHING_H
|
||||
|
||||
#include "map.h"
|
||||
|
||||
#include "zone_config.h"
|
||||
#include <deque>
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
|
||||
class Client;
|
||||
class Mob;
|
||||
|
||||
|
||||
+356
-45
@@ -1072,7 +1072,7 @@ XS(XS_Client_SetBindPoint)
|
||||
new_z = (float)SvNV(ST(5));
|
||||
}
|
||||
|
||||
THIS->SetBindPoint(to_zone, to_instance, glm::vec3(new_x, new_y, new_z));
|
||||
THIS->SetBindPoint(0, to_zone, to_instance, glm::vec3(new_x, new_y, new_z));
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -1940,7 +1940,7 @@ XS(XS_Client_GetSkill)
|
||||
Client * THIS;
|
||||
uint16 RETVAL;
|
||||
dXSTARG;
|
||||
SkillUseTypes skill_id = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -1967,7 +1967,7 @@ XS(XS_Client_GetRawSkill)
|
||||
Client * THIS;
|
||||
uint32 RETVAL;
|
||||
dXSTARG;
|
||||
SkillUseTypes skill_id = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -1993,7 +1993,7 @@ XS(XS_Client_HasSkill)
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
SkillUseTypes skill_id = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -2020,7 +2020,7 @@ XS(XS_Client_CanHaveSkill)
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
SkillUseTypes skill_id = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skill_id = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
@@ -2046,7 +2046,7 @@ XS(XS_Client_SetSkill)
|
||||
Perl_croak(aTHX_ "Usage: Client::SetSkill(THIS, skill_num, value)");
|
||||
{
|
||||
Client * THIS;
|
||||
SkillUseTypes skill_num = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skill_num = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
uint16 value = (uint16)SvUV(ST(2));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
@@ -2071,7 +2071,7 @@ XS(XS_Client_AddSkill)
|
||||
Perl_croak(aTHX_ "Usage: Client::AddSkill(THIS, skillid, value)");
|
||||
{
|
||||
Client * THIS;
|
||||
SkillUseTypes skillid = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
uint16 value = (uint16)SvUV(ST(2));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
@@ -2121,7 +2121,7 @@ XS(XS_Client_CheckIncreaseSkill)
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
SkillUseTypes skillid = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
int chancemodi;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
@@ -2180,7 +2180,7 @@ XS(XS_Client_MaxSkill)
|
||||
{
|
||||
Client * THIS;
|
||||
uint16 RETVAL;
|
||||
SkillUseTypes skillid = (SkillUseTypes)SvUV(ST(1));
|
||||
EQEmu::skills::SkillType skillid = (EQEmu::skills::SkillType)SvUV(ST(1));
|
||||
uint16 class_ = 0;
|
||||
uint16 level = 0;
|
||||
dXSTARG;
|
||||
@@ -2445,6 +2445,30 @@ XS(XS_Client_UnmemSpell)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_UnmemSpellBySpellID); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_UnmemSpellBySpellID)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Client::UnmemSpellBySpellID(THIS, spell_id)");
|
||||
{
|
||||
Client * THIS;
|
||||
int32 spell_id = (int32)SvIV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->UnmemSpellBySpellID(spell_id);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_UnmemSpellAll); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_UnmemSpellAll)
|
||||
{
|
||||
@@ -2568,6 +2592,57 @@ XS(XS_Client_UnscribeSpellAll)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_TrainDiscBySpellID); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_TrainDiscBySpellID)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Client::TrainDiscBySpellID(THIS, spell_id)");
|
||||
{
|
||||
Client * THIS;
|
||||
int32 spell_id = (int32)SvIV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->TrainDiscBySpellID(spell_id);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_GetDiscSlotBySpellID); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GetDiscSlotBySpellID)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Client::GetDiscSlotBySpellID(THIS, spell_id)");
|
||||
{
|
||||
Client * THIS;
|
||||
int RETVAL;
|
||||
int32 spell_id = (int32)SvIV(ST(1));
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetDiscSlotBySpellID(spell_id);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_UntrainDisc); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_UntrainDisc)
|
||||
{
|
||||
@@ -3899,7 +3974,7 @@ XS(XS_Client_GetClientVersion)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = static_cast<unsigned int>(THIS->GetClientVersion());
|
||||
RETVAL = static_cast<unsigned int>(THIS->ClientVersion());
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -3925,7 +4000,7 @@ XS(XS_Client_GetClientVersionBit)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetClientVersionBit();
|
||||
RETVAL = THIS->ClientVersionBit();
|
||||
XSprePUSH; PUSHu((UV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@@ -4077,33 +4152,7 @@ XS(XS_Client_RefundAA) {
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
int curpt = 0;
|
||||
bool refunded = false;
|
||||
|
||||
for(int x1=0;x1<aaHighestID;x1++){
|
||||
curpt = THIS->GetAA(x1);
|
||||
if(curpt > 0){
|
||||
SendAA_Struct* curaa = zone->FindAA(x1);
|
||||
if(curaa){
|
||||
THIS->SetAA(x1, 0);
|
||||
for(int x2=0;x2<curpt;x2++){ //add up all the AA points pt by pt to get the correct cost
|
||||
THIS->GetPP().aapoints += curaa->cost + (curaa->cost_inc * x2);
|
||||
refunded = true;
|
||||
}
|
||||
}
|
||||
else //aa doesn't exist.. but if they bought it then it had at least a cost of 1 point each
|
||||
{ //so give back what we can
|
||||
THIS->GetPP().aapoints += curpt;
|
||||
THIS->SetAA(x1, 0);
|
||||
refunded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(refunded){
|
||||
THIS->Save(); //save of course
|
||||
THIS->Kick(); //client gets all buggy if we don't immediatly relog so just force it on them
|
||||
}
|
||||
THIS->RefundAA();
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -4915,11 +4964,44 @@ XS(XS_Client_IncrementAA)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->IncrementAA(aaskillid);
|
||||
THIS->IncrementAlternateAdvancementRank(aaskillid);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_GrantAlternateAdvancementAbility); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GrantAlternateAdvancementAbility)
|
||||
{
|
||||
dXSARGS;
|
||||
if(items < 3 || items > 4)
|
||||
Perl_croak(aTHX_ "Usage: Client::GrantAlternateAdvancementAbility(THIS, aa_id, points, [ignore_cost])");
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
int aa_id = (int)SvIV(ST(1));
|
||||
int points = (int)SvIV(ST(2));
|
||||
bool ignore_cost = false;
|
||||
|
||||
if(sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
if(items > 3) {
|
||||
ignore_cost = (bool)SvTRUE(ST(3));
|
||||
}
|
||||
|
||||
RETVAL = THIS->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_GetAALevel);
|
||||
XS(XS_Client_GetAALevel)
|
||||
{
|
||||
@@ -5119,13 +5201,20 @@ XS(XS_Client_AssignTask); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_AssignTask)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: Client::AssignTask(THIS, TaskID, NPCID)");
|
||||
if (items != 3 && items != 4)
|
||||
Perl_croak(aTHX_ "Usage: Client::AssignTask(THIS, TaskID, NPCID, enforce_level_requirement)");
|
||||
{
|
||||
Client * THIS;
|
||||
int TaskID = (int)SvIV(ST(1));
|
||||
int NPCID = (int)SvIV(ST(2));
|
||||
|
||||
bool enforce_level_requirement = false;
|
||||
if (items == 4)
|
||||
{
|
||||
if ((int)SvIV(ST(3)) == 1)
|
||||
{
|
||||
enforce_level_requirement = true;
|
||||
}
|
||||
}
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
@@ -5135,7 +5224,7 @@ XS(XS_Client_AssignTask)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->AssignTask(TaskID, NPCID);
|
||||
THIS->AssignTask(TaskID, NPCID, enforce_level_requirement);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
@@ -6110,6 +6199,218 @@ XS(XS_Client_SendSpellAnim)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_GetTargetRingX); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GetTargetRingX)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::GetTargetRingX(THIS)");
|
||||
{
|
||||
Client * THIS;
|
||||
float RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetTargetRingX();
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_GetTargetRingY); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GetTargetRingY)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::GetTargetRingY(THIS)");
|
||||
{
|
||||
Client * THIS;
|
||||
float RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetTargetRingY();
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_GetTargetRingZ); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_GetTargetRingZ)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::GetTargetRingZ(THIS)");
|
||||
{
|
||||
Client * THIS;
|
||||
float RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetTargetRingZ();
|
||||
XSprePUSH; PUSHn((double)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_CalcEXP); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_CalcEXP)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 1 || items > 2)
|
||||
Perl_croak(aTHX_ "Usage: CalcEXP(THIS, uint8 conlevel)");
|
||||
{
|
||||
Client * THIS;
|
||||
uint8 conlevel = 0xFF;
|
||||
uint32 RETVAL;
|
||||
if(items == 2)
|
||||
conlevel = (uint16)SvUV(ST(1));
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == NULL)
|
||||
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->CalcEXP(conlevel);
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_QuestReward); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_QuestReward)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items < 1 || items > 9)
|
||||
Perl_croak(aTHX_ "Usage: Client::QuestReward(THIS, mob, copper, silver, gold, platinum, itemid, exp, faction)");
|
||||
{
|
||||
Client* THIS;
|
||||
Mob * mob = nullptr;
|
||||
int32 copper = 0;
|
||||
int32 silver = 0;
|
||||
int32 gold = 0;
|
||||
int32 platinum = 0;
|
||||
int32 itemid = 0;
|
||||
int32 exp = 0;
|
||||
bool faction = false;
|
||||
|
||||
if (sv_derived_from(ST(0), "THIS")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type client");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
if (items > 1) {
|
||||
if (sv_derived_from(ST(1), "mob")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(1)));
|
||||
mob = INT2PTR(Mob *, tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "mob is not of type Mob");
|
||||
if (mob == nullptr)
|
||||
Perl_croak(aTHX_ "mob is nullptr, avoiding crash.");
|
||||
}
|
||||
if (items > 2) { copper = (int32)SvIV(ST(2)); }
|
||||
if (items > 3) { silver = (int32)SvIV(ST(3)); }
|
||||
if (items > 4) { gold = (int32)SvIV(ST(4)); }
|
||||
if (items > 5) { platinum = (int32)SvIV(ST(5)); }
|
||||
if (items > 6) { itemid = (int32)SvIV(ST(6)); }
|
||||
if (items > 7) { exp = (int32)SvIV(ST(7)); }
|
||||
if (items > 8) { faction = (bool)SvIV(ST(8)); }
|
||||
|
||||
THIS->QuestReward(mob, copper, silver, gold, platinum, itemid, exp, faction);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_GetMoney);
|
||||
XS(XS_Client_GetMoney)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 3)
|
||||
Perl_croak(aTHX_ "Usage: GetMoney(THIS, type, subtype)");
|
||||
{
|
||||
Client* THIS;
|
||||
uint32 RETVAL;
|
||||
uint8 type = (uint8)SvUV(ST(1));
|
||||
uint8 subtype = (uint8)SvUV(ST(2));
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetMoney(type, subtype);
|
||||
XSprePUSH; PUSHn((uint32)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_GetAccountAge);
|
||||
XS(XS_Client_GetAccountAge) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: GetAccountAge(THIS)");
|
||||
{
|
||||
Client* THIS;
|
||||
int RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetAccountAge();
|
||||
XSprePUSH; PUSHn((int)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
@@ -6217,10 +6518,13 @@ XS(boot_Client)
|
||||
newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$");
|
||||
newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$");
|
||||
newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$");
|
||||
newXSproto(strcpy(buf, "ScribeSpell"), XS_Client_ScribeSpell, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$");
|
||||
newXSproto(strcpy(buf, "TrainDiscBySpellID"), XS_Client_TrainDiscBySpellID, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$");
|
||||
newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "UntrainDiscAll"), XS_Client_UntrainDiscAll, file, "$;$");
|
||||
newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$");
|
||||
@@ -6307,13 +6611,14 @@ XS(boot_Client)
|
||||
newXSproto(strcpy(buf, "GetIP"), XS_Client_GetIP, file, "$");
|
||||
newXSproto(strcpy(buf, "AddLevelBasedExp"), XS_Client_AddLevelBasedExp, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "IncrementAA"), XS_Client_IncrementAA, file, "$$");
|
||||
newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "GetAALevel"), XS_Client_GetAALevel, file, "$$");
|
||||
newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$");
|
||||
newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$");
|
||||
newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$");
|
||||
newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$");
|
||||
newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$");
|
||||
newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$");
|
||||
newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$");
|
||||
newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$");
|
||||
newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$");
|
||||
@@ -6351,7 +6656,13 @@ XS(boot_Client)
|
||||
newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$");
|
||||
newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$");
|
||||
newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$");
|
||||
|
||||
newXSproto(strcpy(buf, "GetTargetRingX"), XS_Client_GetTargetRingX, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetTargetRingY"), XS_Client_GetTargetRingY, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetTargetRingZ"), XS_Client_GetTargetRingZ, file, "$$");
|
||||
newXSproto(strcpy(buf, "QuestReward"), XS_Client_QuestReward, file, "$$;$$$$$$$");
|
||||
newXSproto(strcpy(buf, "CalcEXP"), XS_Client_CalcEXP, file, "$");
|
||||
newXSproto(strcpy(buf, "GetMoney"), XS_Client_GetMoney, file, "$$$");
|
||||
newXSproto(strcpy(buf, "GetAccountAge"), XS_Client_GetAccountAge, file, "$");
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -1904,7 +1904,7 @@ XS(XS_EntityList_GetMobList)
|
||||
|
||||
std::list<Mob*> mob_list;
|
||||
entity_list.GetMobList(mob_list);
|
||||
std::list<Mob*>::iterator iter = mob_list.begin();
|
||||
auto iter = mob_list.begin();
|
||||
|
||||
while(iter != mob_list.end())
|
||||
{
|
||||
@@ -1941,7 +1941,7 @@ XS(XS_EntityList_GetClientList)
|
||||
|
||||
std::list<Client*> client_list;
|
||||
entity_list.GetClientList(client_list);
|
||||
std::list<Client*>::iterator iter = client_list.begin();
|
||||
auto iter = client_list.begin();
|
||||
|
||||
while(iter != client_list.end())
|
||||
{
|
||||
@@ -1978,7 +1978,7 @@ XS(XS_EntityList_GetNPCList)
|
||||
|
||||
std::list<NPC*> npc_list;
|
||||
entity_list.GetNPCList(npc_list);
|
||||
std::list<NPC*>::iterator iter = npc_list.begin();
|
||||
auto iter = npc_list.begin();
|
||||
|
||||
while(iter != npc_list.end())
|
||||
{
|
||||
@@ -2015,7 +2015,7 @@ XS(XS_EntityList_GetCorpseList)
|
||||
|
||||
std::list<Corpse*> corpse_list;
|
||||
entity_list.GetCorpseList(corpse_list);
|
||||
std::list<Corpse*>::iterator iter = corpse_list.begin();
|
||||
auto iter = corpse_list.begin();
|
||||
|
||||
while(iter != corpse_list.end())
|
||||
{
|
||||
@@ -2052,7 +2052,7 @@ XS(XS_EntityList_GetObjectList)
|
||||
|
||||
std::list<Object*> object_list;
|
||||
entity_list.GetObjectList(object_list);
|
||||
std::list<Object*>::iterator iter = object_list.begin();
|
||||
auto iter = object_list.begin();
|
||||
|
||||
while(iter != object_list.end())
|
||||
{
|
||||
@@ -2089,7 +2089,7 @@ XS(XS_EntityList_GetDoorsList)
|
||||
|
||||
std::list<Doors*> door_list;
|
||||
entity_list.GetDoorsList(door_list);
|
||||
std::list<Doors*>::iterator iter = door_list.begin();
|
||||
auto iter = door_list.begin();
|
||||
|
||||
while(iter != door_list.end())
|
||||
{
|
||||
|
||||
+743
-73
File diff suppressed because it is too large
Load Diff
@@ -2530,6 +2530,32 @@ XS(XS_NPC_ClearLastName)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_NPC_GetCombatState); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_NPC_GetCombatState)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: NPC::GetCombatState(THIS)");
|
||||
{
|
||||
NPC * THIS;
|
||||
bool RETVAL;
|
||||
|
||||
if (sv_derived_from(ST(0), "NPC")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(NPC *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetCombatEvent();
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
@@ -2643,6 +2669,7 @@ XS(boot_NPC)
|
||||
newXSproto(strcpy(buf, "RemoveDefensiveProc"), XS_NPC_RemoveDefensiveProc, file, "$$");
|
||||
newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$");
|
||||
newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$");
|
||||
newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$");
|
||||
XSRETURN_YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ XS(XS_QuestItem_IsType)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->IsType((ItemClassTypes)type);
|
||||
RETVAL = THIS->IsType((EQEmu::item::ItemClass)type);
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
|
||||
+2
-2
@@ -62,7 +62,7 @@ void PerlPacket::SendTo(Client *who) {
|
||||
if(!who || op == OP_Unknown || (len > 0 && packet == nullptr))
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(op, len);
|
||||
auto outapp = new EQApplicationPacket(op, len);
|
||||
if(len > 0)
|
||||
memcpy(outapp->pBuffer, packet, len);
|
||||
|
||||
@@ -76,7 +76,7 @@ void PerlPacket::SendToAll() {
|
||||
if(op == OP_Unknown || (len > 0 && packet == nullptr))
|
||||
return;
|
||||
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(op, len);
|
||||
auto outapp = new EQApplicationPacket(op, len);
|
||||
if(len > 0)
|
||||
memcpy(outapp->pBuffer, packet, len);
|
||||
entity_list.QueueClients(nullptr, outapp, false);
|
||||
|
||||
+3
-3
@@ -44,7 +44,7 @@ PetitionList petition_list;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void Petition::SendPetitionToPlayer(Client* clientto) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_PetitionCheckout,sizeof(Petition_Struct));
|
||||
auto outapp = new EQApplicationPacket(OP_PetitionCheckout, sizeof(Petition_Struct));
|
||||
Petition_Struct* pet = (Petition_Struct*) outapp->pBuffer;
|
||||
strcpy(pet->accountid,this->GetAccountName());
|
||||
strcpy(pet->lastgm,this->GetLastGM());
|
||||
@@ -136,7 +136,7 @@ bool PetitionList::DeletePetitionByCharName(const char* charname) {
|
||||
return false;
|
||||
}
|
||||
void PetitionList::UpdateZoneListQueue() {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_Petition, sizeof(ServerPetitionUpdate_Struct));
|
||||
auto pack = new ServerPacket(ServerOP_Petition, sizeof(ServerPetitionUpdate_Struct));
|
||||
ServerPetitionUpdate_Struct* pupdate = (ServerPetitionUpdate_Struct*) pack->pBuffer;
|
||||
pupdate->petid = 0x00;
|
||||
pupdate->status = 0x00;
|
||||
@@ -229,7 +229,7 @@ void ZoneDatabase::InsertPetitionToDB(Petition* wpet)
|
||||
{
|
||||
|
||||
uint32 len = strlen(wpet->GetPetitionText());
|
||||
char* petitiontext = new char[2*len+1];
|
||||
auto petitiontext = new char[2 * len + 1];
|
||||
memset(petitiontext, 0, 2*len+1);
|
||||
DoEscapeString(petitiontext, wpet->GetPetitionText(), len);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user