-
Notifications
You must be signed in to change notification settings - Fork 241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Review Request / Merge : Move to Object, Move to Position, Turn to Object, Turn to Position #328
Conversation
…ate Machine added - one bug left.
session.Player.BlockedGameAction = null; | ||
session.Player.MoveToPosition = null; | ||
session.Player.ArrivedRadiusSquared = 0.00f; | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
end file on new line please
Unlocked, | ||
InUse, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline eof
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@LtRipley36706 fixed. BTW did you do the move ci & create to debugObject? I think when you did the full rest it brought that code in. There is a bug - it will not spawn 12748 (training wand) in the backpack using ci. It will float it mid air using create, but it thinks it is a PK alter. I started looking at it - but while I think the way you implemented it is awesome - I am not sure I fully understand it. I am trying to work through the code now. If / when you had a minute to take a look - that would be awesome. |
Arrived, | ||
Abandoned, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline eof
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. Sorry - I am aware of that now and will make sure I am doing it correctly going forward.
changelog.md
Outdated
* State Machine | ||
* Currently one last bug to be addressed but wanted to get this in. | ||
|
||
### 2017-05-04 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove duplicated date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
…s :) Sorry about that. I will remember going forward.
@ogmage78 yeah I swapped ci/create DebugObject to get the debug data for assess. The problem is DebugObject is trying to be this generic catch all and I'm not even sure it can be, adding in too much stuff alters how an object was really setup in retail. As of this moment, I'm still of the belief that essentially we're needing a 1:1 recreation of each weenie in the codebase so in order to properly spawn a Training Wand, you need a TrainingWand.cs weenie file with all the proper settings in there, and then we need a "factory" that searches and finds the right weenie to create an object from, assuming a weenie code file has been created for the object. |
@LtRipley36706 @Mogwai-AC Not dead set against that - but maybe it is just the database guy in me - see a db approach as a better choice. It seems what we need i(f I understand a weenie class correctly) the weenie class is the base template from which 0-N variations are all derived. Some like the training wand - is really the base and that is it. If we made weenie_class have all of the base data then have a 1 to N relationship to base ace object that would do the trick. Let's look at the use case of creating loot. Let's say we want to spawn armor for a corpse loot drop. Random pick the weenie class from the type armor. Pull up that base weenie class. Now do your mutations. Now - you can do the same thing with a file / class for every weenie class - I am not really sure if one way is better than the other. If we go db route, we could do one per type - armor, weapons, clothes etc many fewer files and going forward - a way to have content creators be able to create new things without code changes. Let me know what you think. I added Mogwai just to get his opinion. I don't feel strongly either way - and can work with whatever we decide. |
I am not yet convinced why we can't create most if not all base items / objects only based on their weenie from the database. When it comes to variations we will need some coding for it, which may be sensible to have in their own classes: I.e. to create the random variance in weapon damage is another formula than to create the random AL some armor items got. |
When it comes to monsters, the weenie is essentially all that matters. The debate is whether or not it applies to NPCs, portals, etc. Items start from the weenies, but the buffs and stats are what vary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In summary, I'm ok with the heart of the changes. I want that state machine to be named "movementStateMachine" (because we will have others) and to be private in the player. The player controls the state machine, not all the network handlers.
if (session.Player.Statemachine.CurrentState != (int)MovementStates.Moving) return; | ||
if ((Math.Abs(session.Player.PhysicsData.Position.SquaredDistanceTo(session.Player.MoveToPosition)) <= session.Player.ArrivedRadiusSquared)) | ||
{ | ||
session.Player.Statemachine.ChangeState((int)MovementStates.Arrived); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like hitting the StateMachine of the Player from here. Perhaps we have a session.Player.OnArrived() method?
We'd also have a session.Player.IsPerformingMoveAction that his the state machine.
edit: even better: session.Player.OnAutonomousMove() that does it all. It would also do the call to UpdatePosition, I think.
Source/ACE/Entity/Creature.cs
Outdated
/// <summary> | ||
/// Track state of creature if their current action is blocked. Either until they are no longer blocked or the action is abandoned. | ||
/// </summary> | ||
public StateMachine Statemachine = new StateMachine(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd really rather this be private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
@@ -92,6 +92,15 @@ public static void Handle(ClientMessage message, Session session) | |||
forcePositionTimestamp = message.Payload.ReadUInt16(); | |||
message.Payload.ReadByte(); | |||
|
|||
if (session.Player.Statemachine.CurrentState == (int)MovementStates.Moving) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above, session.Player.OnActionMoveToState(ushort timestamp) or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do.
@@ -18,6 +19,8 @@ public GameMessageAutonomousPosition(WorldObject worldObject) | |||
Writer.Write(worldObject.Sequences.GetCurrentSequence(SequenceType.ObjectTeleport)); // teleport_timestamp - always 0 in my pcaps | |||
Writer.Write(worldObject.Sequences.GetCurrentSequence(SequenceType.ObjectForcePosition)); // force_position_timestamp - always 0 in my pcaps | |||
Writer.Write(1u); // contact - always "true" / 1 in my pcaps | |||
if (p.Statemachine.CurrentState == (int)MovementStates.Idle) | |||
p.Statemachine.ChangeState((int)MovementStates.Moving); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, if we make StateMachine private, you force this logic into the player class where it belongs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing
writer.Write(WalkRunThreshold); | ||
writer.Write(heading); | ||
writer.Write(RunRate); | ||
// TODO: This needs to be calculated and the flag needs to be deciphered Og II |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yay properties instead of magic values 👍
…Please review for the changes you requested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work on the changes to the state machine. You resurrected a bad method though.
Source/ACE/Entity/Landblock.cs
Outdated
/// </summary> | ||
/// <param name="objectGuid"></param> | ||
/// <returns></returns> | ||
public WorldObject GetWorldObjectByGuid(ObjectGuid objectGuid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writer.Write(worldObject.Sequences.GetCurrentSequence(SequenceType.ObjectForcePosition)); // force_position_timestamp - always 0 in my pcaps | ||
Writer.Write(1u); // contact - always "true" / 1 in my pcaps | ||
} | ||
if (!(worldObject is Player)) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skipping the { } is ok, putting return on the same line is not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will get this - I really will :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still needs fixing.
Source/ACE/Entity/Landblock.cs
Outdated
var arrivedRadius = (float)Math.Pow((targetWorldObject.GameData.UseRadius + csetup.Radius + 1.5), 2); | ||
|
||
// are we close enough? If so, our work here is done. | ||
if ((player.PhysicsData.Position.SquaredDistanceTo(targetWorldObject.PhysicsData.Position) <= arrivedRadius)) return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return on it's own line, please.
Source/ACE/Entity/Landblock.cs
Outdated
player.MoveToPosition = targetWorldObject.PhysicsData.Position; | ||
player.ArrivedRadiusSquared = arrivedRadius; | ||
player.BlockedGameAction = action; | ||
player.OnAutonomousMove(targetWorldObject, movementType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, checking for "InRangeForAction" triggers an OnAutonomousMove? This defies logic to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea now that you point it out - a combined two actions that should each be their own method. I think I have to do all the math to see if I am in range. I am setting a destination, a range and saving off the original action (pick something up, use something etc) and then starting on the way. I guess the best way to do it is to have InRangeForAction return arrivedRadiusSquared - if non 0 then I can take the appropriate action. So let it be written, so let it be done.
I think all the bugs are fixed and all of the changes are complete. |
@@ -77,6 +77,7 @@ public DebugObject(ObjectGuid guid, BaseAceObject baseAceObject) | |||
// Creating from a pcap of the weenie - this will be set by the loot generation factory. Og II | |||
this.PhysicsData.PhysicsDescriptionFlag &= ~PhysicsDescriptionFlag.Parent; | |||
this.GameData.ValidLocations = (EquipMask)baseAceObject.ValidLocations; | |||
this.GameData.IconOverlay = (ushort)baseAceObject.IconOverlayId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Icons are packed dwords in most places. I doubt this cast is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GameData.IconOverlay is defined as a ushort. The iconOverlayId is defined in BaseAceObject as an int. It is an int in the data as well. so do I take out the 0x06000000 from the number in the database and just store last 4 up to FFFF which will fit in a ushort or change or change gameData? I am assuming strip the number - I need to make sure the writer is adding the 0x6000000 back to to iconoverlay and underlay first. Let me know and I will fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly we went the way of changing the type to int in the other cases were this was a problem as well, i.e. textures, palettes, etc.
Source/ACE/Entity/Landblock.cs
Outdated
@@ -276,7 +276,7 @@ public List<WorldObject> GetWorldObjectsInRange(WorldObject wo, float maxrange, | |||
return allworldobj; | |||
} | |||
|
|||
public List<WorldObject> GetWorldObjectsByGuid(ObjectGuid objectguid, bool neighbors) | |||
private List<WorldObject> GetWorldObjectsByGuid(ObjectGuid objectguid, bool neighbors) | |||
{ | |||
List<WorldObject> allworldobj = new List<WorldObject>(); | |||
lock (objectCacheLocker) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copying the list, then looking for 1 object is a hell of a lot slower than just looking for the 1 while you have the lock.
Source/ACE/Entity/Landblock.cs
Outdated
@@ -276,7 +276,7 @@ public List<WorldObject> GetWorldObjectsInRange(WorldObject wo, float maxrange, | |||
return allworldobj; | |||
} | |||
|
|||
public List<WorldObject> GetWorldObjectsByGuid(ObjectGuid objectguid, bool neighbors) | |||
private List<WorldObject> GetWorldObjectsByGuid(ObjectGuid objectguid, bool neighbors) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Guid is unique. Or it is designed to be so, anyway. Duplicate guids = big bug. Returning a List here is a waste.
- Locking just to copy the entire list is a waste. Check for the item in the lock.
- If you find it here, there's no reason to hit the adjacencies.
- If you find it in an adjacency, either return or continue out of the loop to stop looking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed that I could use the other call and search adjcency - this is something stackoverflow put it - because I did not realize that the other could do what I wanted - I used this to search the landblock plus adj. I thought it was funky but I was concentrating on finding my damn bug and did not really think about it.
@@ -77,6 +77,7 @@ public DebugObject(ObjectGuid guid, BaseAceObject baseAceObject) | |||
// Creating from a pcap of the weenie - this will be set by the loot generation factory. Og II | |||
this.PhysicsData.PhysicsDescriptionFlag &= ~PhysicsDescriptionFlag.Parent; | |||
this.GameData.ValidLocations = (EquipMask)baseAceObject.ValidLocations; | |||
this.GameData.IconOverlay = (ushort)baseAceObject.IconOverlayId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elsewhere, Icon is a Packed DWORD. I doubt this cast is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^^ above
Source/ACE/Entity/Landblock.cs
Outdated
/// <returns></returns> | ||
private WorldObject GetWorldObjectByGuid(ObjectGuid objectGuid) | ||
{ | ||
var objectList = GetWorldObjectsByGuid(objectGuid, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See, this is the method you needed, but with the adjacency flag. Combine this with the bad method above.
Writer.Write(worldObject.Sequences.GetCurrentSequence(SequenceType.ObjectForcePosition)); // force_position_timestamp - always 0 in my pcaps | ||
Writer.Write(1u); // contact - always "true" / 1 in my pcaps | ||
} | ||
if (!(worldObject is Player)) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still needs fixing.
@@ -9,6 +9,16 @@ namespace ACE.Network.Motion | |||
public class UniversalMotion : MotionState | |||
{ | |||
public uint Flag { get; set; } = 0x0041EE0F; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whitespace lines between members
|
||
private static int initstate = (int)ContainerStates.Unlocked; | ||
|
||
private static readonly List<Rule> Rulesstates = new List<Rule>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private members = camel case (rulesStates)
{ | ||
private static bool init = false; | ||
|
||
private static int initstate = (int)ContainerStates.Unlocked; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
camel case (initState)
{ | ||
public class StateMachine | ||
{ | ||
private List<Rule> validrules; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
camel case (validRules) and whitespace lines
…nd replace. Fixed bug in state machine, addressed Mogwai's issues.
Ok - I think this is ready for another review.
|
This is 99% of the way there. I have a bug I am having trouble tracking down. I think this is solid code once we hit that last bug. It does not break anything and we have a lot of people working on items related to this. The sooner this is merged - the better. In the absence of finding the bug, I would propose merging it anyway to get the core in.
To see the bug. @ci 12748 will create a training wand in your back pack. Drop it, move off - select it. It should put your pick up item on hold, move you to the position, then once in range pick up the wand. I was moving but now it is not. It has to be something simple, it was working before. Please advise.
One more thing - there are 4 files that show changes that I did nothing to - they show complete file replacements. I did not even edit them. Not sure why that is happening.
SetModel.cs, Extensions.cs - the solutions files - no idea why they show complete replace and no idea how to stop it or fix it.