fixed mob loading from db

- todo: see todos in code (all 169 of them)
This commit is contained in:
Tahir Akhlaq 2017-09-07 22:02:02 +01:00
parent 7c30b95c4b
commit 645a1fb4fb
12 changed files with 169 additions and 82 deletions

View file

@ -427,46 +427,61 @@ namespace FFXIVClassic_Map_Server
{
conn.Open();
var query = @"
SELECT bsl.uniqueId, bsl.groupId, bsl.positionX, bsl.positionY, bsl.positionZ, bsl.rotation,
bgr.groupId, bgr.genusId, bgr.actorClassId, bgr.minLevel, bgr.maxLevel, bgr.respawnTime,
bgr.hp, bgr.mp, bgr.skillListId, bgr.spellListId, bgr.dropListId, bgr.allegiance,
bgr.spawnType, bgr.animationId, bgr.actorState, bgr.privateAreaName, bgr.privateAreaLevel, bgr.zoneId,
SELECT bsl.groupId, bsl.positionX, bsl.positionY, bsl.positionZ, bsl.rotation,
bgr.groupId, bgr.poolId, bgr.actorClassId, bgr.scriptName, bgr.minLevel, bgr.maxLevel, bgr.respawnTime, bgr.hp, bgr.mp,
bgr.dropListId, bgr.allegiance, bgr.spawnType, bgr.animationId, bgr.actorState, bgr.privateAreaName, bgr.privateAreaLevel, bgr.zoneId,
bpo.poolId, bpo.genusId, bpo.currentJob, bpo.combatSkill, bpo.combatDelay, bpo.combatDmgMult, bpo.aggroType,
bpo.immunity, bpo.linkType, bpo.skillListId, bpo.spellListId,
bge.genusId, bge.modelSize, bge.kindredId, bge.detection, bge.hpp, bge.mpp, bge.tpp, bge.str, bge.vit, bge.dex,
bge.int, bge.mnd, bge.pie, bge.att, bge.acc, bge.def, bge.eva, bge.slash, bge.pierce, bge.h2h, bge.blunt,
bge.fire, bge.ice, bge.wind, bge.lightning, bge.earth, bge.water FROM
server_battlenpc_spawn_locations bsl INNER JOIN server_battlenpc_groups bgr ON bsl.groupId = bgr.groupId INNER JOIN
server_battlenpc_genus bge ON bgr.genusId = bgr.genusId WHERE bgr.zoneId = {0} GROUP BY bsl.bnpcIndex;
bge.fire, bge.ice, bge.wind, bge.lightning, bge.earth, bge.water
FROM server_battlenpc_spawn_locations bsl
INNER JOIN server_battlenpc_groups bgr ON bsl.groupId = bgr.groupId
INNER JOIN server_battlenpc_pools bpo ON bgr.poolId = bpo.poolId
INNER JOIN server_battlenpc_genus bge ON bpo.genusId = bge.genusId
WHERE bgr.zoneId = @zoneId GROUP BY bsl.bnpcIndex;
";
Debugger.Break();
foreach (var zone in zoneList.Values)
var count = 0;
foreach (var zonePair in zoneList)
{
query = String.Format(query, zone.GetZoneID());
var zone = zonePair.Value;
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@zoneId", zonePair.Key);
cmd.ExecuteNonQuery();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int actorId = zone.GetActorCount() + 1;
// todo: add to private areas, set up immunity, mob linking,
// - load skill/spell/drop lists, set npcWork.hateType,
var battleNpc = new BattleNpc(actorId, Server.GetWorldManager().GetActorClass(reader.GetUInt32("actorClassId")),
reader.GetString("uniqueId"), zone, reader.GetFloat("positionX"), reader.GetFloat("positionY"), reader.GetFloat("positionZ"), reader.GetFloat("rotation"),
reader.GetString("scriptName"), zone, reader.GetFloat("positionX"), reader.GetFloat("positionY"), reader.GetFloat("positionZ"), reader.GetFloat("rotation"),
reader.GetUInt16("actorState"), reader.GetUInt32("animationId"), "");
battleNpc.neutral = reader.GetByte("aggroType") == 0;
battleNpc.SetDetectionType(reader.GetUInt32("detection"));
battleNpc.kindredType = (KindredType)reader.GetUInt32("kindredId");
battleNpc.npcSpawnType = (NpcSpawnType)reader.GetUInt32("spawnType");
// todo: set hateType to appropriate detectionType thing
//battleNpc.npcWork.hateType
battleNpc.charaWork.parameterSave.state_mainSkill[0] = reader.GetByte("currentJob");
battleNpc.charaWork.parameterSave.state_mainSkillLevel = (short)Program.Random.Next(reader.GetByte("minLevel"), reader.GetByte("maxLevel"));
battleNpc.allegiance = (CharacterTargetingAllegiance)reader.GetByte("allegiance");
// todo: setup private areas and other crap and
// set up rest of stat resists
battleNpc.SetMod((uint)Modifier.Hp, reader.GetUInt32("hp"));
battleNpc.SetMod((uint)Modifier.HpPercent, reader.GetUInt32("hpp"));
battleNpc.SetMod((uint)Modifier.Mp, reader.GetUInt32("mp"));
battleNpc.SetMod((uint)Modifier.MpPercent, reader.GetUInt32("mpp"));
battleNpc.SetMod((uint)Modifier.Tp, reader.GetUInt32("tp"));
battleNpc.SetMod((uint)Modifier.TpPercent, reader.GetUInt32("tpp"));
battleNpc.SetMod((uint)Modifier.Strength, reader.GetUInt32("str"));
@ -480,19 +495,19 @@ namespace FFXIVClassic_Map_Server
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
//battleNpc.SetMod((uint)Modifier.ResistFire, )
battleNpc.SetAggroType(reader.GetUInt32("detection"));
// todo: load spell/skill/drop lists
battleNpc.dropListId = reader.GetUInt32("dropListId");
battleNpc.spellListId = reader.GetUInt32("spellListId");
battleNpc.skillListId = reader.GetUInt32("skillListId");
//battleNpc.SetMod((uint)Modifier.ResistFire, )
zone.AddActorToZone(battleNpc);
count++;
}
}
}
Program.Log.Info("Loaded {0} monsters.", count);
}
catch (MySqlException e)
{

View file

@ -109,7 +109,6 @@ namespace FFXIVClassic_Map_Server.Actors
this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
// todo: make this halal
this.moveState = this.oldMoveState;
this.updateFlags |= ActorUpdateFlags.Speed;
}
@ -649,13 +648,13 @@ namespace FFXIVClassic_Map_Server.Actors
rotation = (float)dRot;
}
// todo: is this legit?
public bool IsFacing(float x, float z, float angle = 40.0f)
{
angle = (float)(Math.PI * angle / 180);
return Math.Abs(Vector3.GetAngle(positionX, positionZ, x, z) - rotation) < angle;
}
// todo: is this legit?
public bool IsFacing(Actor target, float angle = 40.0f)
{
if (target == null)

View file

@ -182,18 +182,15 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
public void Clear()
{
// todo:
path?.Clear();
pathFlags = PathFindFlags.None;
distanceFromPoint = 0.0f;
}
private float GetSpeed()
{
float baseSpeed = owner.GetSpeed();
// todo: get actual speed crap
if (!(owner is Player))
{
if (owner is BattleNpc)

View file

@ -381,7 +381,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
this.durationMs = durationMs;
this.tier = tier;
// todo: use tick instead of now?
this.startTime = DateTime.Now;
this.lastTick = startTime;
}
@ -415,19 +414,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
// return true when duration has elapsed
public bool Update(DateTime tick)
{
// todo: maybe not tick if already reached duration?
if (tickMs != 0 && (tick - lastTick).TotalMilliseconds >= tickMs)
{
// todo: call effect's onTick
// todo: maybe keep a global lua object instead of creating a new one each time we wanna call a script
lastTick = tick;
LuaEngine.CallLuaStatusEffectFunction(this.owner, this, "onTick", this.owner, this);
}
// todo: handle infinite duration effects?
if (durationMs != 0 && (tick - startTime).TotalMilliseconds >= durationMs)
{
// todo: call effect's onLose
// todo: broadcast effect lost packet
return true;
}
return false;

View file

@ -73,7 +73,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
32001 [@2B([@IF($E4($EB(1),$EB(2)),you,[@IF($E9(7),[@SHEETEN(xtx/displayName,2,$E9(7),1,1)],$EB(2))])])] [@IF($E4($EB(1),$EB(2)),resist,resists)] the effect of [@SHEET(xtx/status,$E8(11),3)].
32002 [@SHEET(xtx/status,$E8(11),3)] fails to take effect.
*/
// todo: check flags/overwritable and add effect to list
var effect = GetStatusEffectById(newEffect.GetStatusEffectId());
bool canOverwrite = false;
if (effect != null)
@ -100,7 +99,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
{
effects.Add(newEffect.GetStatusEffectId(), newEffect);
newEffect.SetSilent(silent);
// todo: this is retarded..
{
var index = Array.IndexOf(effects.Values.ToArray(), newEffect);
owner.charaWork.status[index] = newEffect.GetStatusId();
@ -128,7 +126,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
}
// todo: this is retarded..
{
var index = Array.IndexOf(effects.Values.ToArray(), effect);
owner.charaWork.status[index] = 0;

View file

@ -150,7 +150,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
{
validTarget = flags;
// todo: maybe this should only be set if successfully added?
this.targetPosition = target.GetPosAsVector3();
AddTarget(target, false);
}
@ -161,7 +160,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
public void FindWithinArea(Character target, ValidTarget flags, TargetFindAOETarget aoeTarget)
{
validTarget = flags;
// todo: maybe we should keep a snapshot which is only updated on each tick for consistency
// are we creating aoe circles around target or self
if (aoeTarget == TargetFindAOETarget.Self)
this.targetPosition = owner.GetPosAsVector3();
@ -182,7 +180,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
{
findType = TargetFindCharacterType.PlayerToPlayer;
// todo: handle player parties
if (masterTarget.currentParty != null)
{
if ((validTarget & (ValidTarget.Ally | ValidTarget.PartyMember)) != 0)
@ -273,7 +270,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
private void AddAllInParty(Character target, bool withPet)
{
// todo:
var party = target.currentParty as Party;
if (party != null)
{
@ -294,10 +290,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
{
var actors = owner.zone.GetActorsAroundActor<BattleNpc>(owner, 50);
// todo: should we look for Characters instead in case player is charmed by BattleNpc
foreach (BattleNpc actor in actors)
{
// todo:
AddTarget(actor, false);
}
}

View file

@ -63,7 +63,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
public override bool Engage(Character target)
{
// todo: check distance, last swing time, status effects
var canEngage = this.owner.aiContainer.InternalEngage(target);
if (canEngage)
{
@ -140,7 +139,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
if (tick >= waitTime)
{
// todo: aggro cooldown
neutralTime = tick.AddSeconds(5);
if (owner.aiContainer.pathFind.IsFollowingPath())
{
@ -154,7 +152,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
}
}
// todo:
waitTime = tick.AddSeconds(10);
owner.OnRoam(tick);
@ -171,11 +168,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{
foreach (var player in owner.zone.GetActorsAroundActor<Player>(owner, 50))
{
if (!owner.isMovingToSpawn && owner.aiContainer.pathFind.AtPoint() && owner.aggroType != AggroType.None)
if (!owner.isMovingToSpawn && owner.aiContainer.pathFind.AtPoint() && owner.detectionType != DetectionType.None)
{
uint levelDifference = (uint)Math.Abs(owner.charaWork.parameterSave.state_mainSkillLevel - player.charaWork.parameterSave.state_mainSkillLevel);
if (levelDifference <= 10 || (owner.aggroType & AggroType.IgnoreLevelDifference) != 0 && CanAggroTarget(player))
if (levelDifference <= 10 || (owner.detectionType & DetectionType.IgnoreLevelDifference) != 0 && CanAggroTarget(player))
{
owner.hateContainer.AddBaseHate(player);
break;
@ -287,7 +284,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
public bool CanAggroTarget(Character target)
{
if (owner.neutral || owner.aggroType == AggroType.None || owner.IsDead())
if (owner.neutral || owner.detectionType == DetectionType.None || owner.IsDead())
{
return false;
}
@ -326,7 +323,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
var distance = Utils.Distance(owner.positionX, owner.positionY, owner.positionZ, target.positionX, target.positionY, target.positionZ);
bool detectSight = forceSight || (owner.aggroType & AggroType.Sight) != 0;
bool detectSight = forceSight || (owner.detectionType & DetectionType.Sight) != 0;
bool hasSneak = false;
bool hasInvisible = false;
bool isFacing = owner.IsFacing(target);
@ -344,7 +341,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
}
if ((owner.aggroType & AggroType.LowHp) != 0 && target.GetHPP() < 75)
if ((owner.detectionType & DetectionType.LowHp) != 0 && target.GetHPP() < 75)
return CanSeePoint(target.positionX, target.positionY, target.positionZ);
if (detectSight && !hasInvisible && isFacing)

View file

@ -45,7 +45,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
}
else
{
// todo: check within attack range
owner.LookAt(target);
}
}

View file

@ -21,14 +21,15 @@ using FFXIVClassic_Map_Server.packets.send;
namespace FFXIVClassic_Map_Server.Actors
{
[Flags]
enum AggroType
enum DetectionType
{
None = 0x00,
Sight = 0x01,
Scent = 0x02,
Sound = 0x04,
LowHp = 0x08,
IgnoreLevelDifference = 0x10
None = 0x00,
Sight = 0x01,
Scent = 0x02,
Sound = 0x04,
LowHp = 0x08,
IgnoreLevelDifference = 0x10,
Magic = 0x20,
}
enum KindredType
@ -49,7 +50,7 @@ namespace FFXIVClassic_Map_Server.Actors
class BattleNpc : Npc
{
public HateContainer hateContainer;
public AggroType aggroType;
public DetectionType detectionType;
public KindredType kindredType;
public bool neutral;
private uint despawnTime;
@ -82,7 +83,7 @@ namespace FFXIVClassic_Map_Server.Actors
spawnZ = posZ;
// todo: read these from db also
aggroType = AggroType.Sight;
detectionType = DetectionType.Sight;
this.moveState = 2;
ResetMoveSpeeds();
despawnTime = 10;
@ -113,14 +114,14 @@ namespace FFXIVClassic_Map_Server.Actors
return subpackets;
}
public uint GetAggroType()
public uint GetDetectionType()
{
return (uint)aggroType;
return (uint)detectionType;
}
public void SetAggroType(uint aggroType)
public void SetDetectionType(uint detectionType)
{
this.aggroType = (AggroType)aggroType;
this.detectionType = (DetectionType)detectionType;
}
public override void Update(DateTime tick)