-
Notifications
You must be signed in to change notification settings - Fork 246
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
Feature: ORM Driven Character Positions for Issue #166 #184
Conversation
Source/ACE/Entity/Player.cs
Outdated
/// <summary> | ||
/// Set's the tied lifestone for use casting the Lifestone Recall spell | ||
/// </summary> | ||
public void SetLifestoneTiedCharacterPosition(CharacterPosition newPosition) |
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.
This begins the stubs for functions we will write in the future.
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.
It seems like we should have a single "SetPosition(Enum.Position positionType, Position position)" method so that we don't have to have 1 of these for each.
character.Position = Session.Player.Position; | ||
|
||
// Save the current position to persistent storage | ||
SetPhysicalCharacterPosition(); |
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.
Loads the Player position into the dictionary of positions before saving in the database.
@@ -132,6 +132,7 @@ public static void CharacterRestore(ClientPacketFragment fragment, Session sessi | |||
uint lowGuid = DatabaseManager.Character.GetMaxId(); | |||
character.Id = lowGuid; | |||
character.AccountId = session.Id; | |||
character.DateOfBirth = character.CreationTimeStamp.ToString(); |
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.
This field was always null before this change.
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.
check /birth command, I'm thinking this property was the same output
@@ -140,7 +141,9 @@ public static void CharacterRestore(ClientPacketFragment fragment, Session sessi | |||
} | |||
|
|||
CharacterCreateSetDefaultCharacterOptions(character); | |||
CharacterCreateSetDefaultCharacterPositions(character); |
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.
Set's the initial values for the character positions, when the character is first created.
/// <param name="session"></param> | ||
/// <param name="parameters"></param> | ||
[CommandHandler("save", AccessLevel.Developer, CommandHandlerFlag.RequiresWorld)] | ||
public static void Save(Session session, params string[] parameters) |
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.
Useful for invoking a database save; I used this instead of logging out or waiting 5 minutes.
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.
There's already a save command in AdminCommands, suggest renaming this to something else
/// <param name="session"></param> | ||
/// <param name="parameters"></param> | ||
[CommandHandler("whoami", AccessLevel.Developer, CommandHandlerFlag.RequiresWorld)] | ||
public static void WhoAmI(Session session, params string[] parameters) |
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.
With multiple characters on screen/per account, this is helpful when comparing columns in the database.
@@ -0,0 +1,139 @@ | |||
namespace ACE.Entity.Enum | |||
{ | |||
public enum CharacterPositionType |
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.
Class to hold character specific positions.
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 opposed to the other Positions enum? are they both needed?
Updated comments on CharacterPositionType Added the sql for altering the positions table, to add the positionType Added ripleys Position Types Added Character Position Database Object Renamed Position types to Positions to Match Ripley's original code. Looks better in character, also. Changed to the correct function when Executing constructed statements Added another debug command Added Position update to the Character Data object Changed the positiontype to a keyed column in mysql DB Updates Morning updates - working position inserts at character creation Updated constructstatement, positions are saving to the right columns Load all available character positions from the database or create a new if missing Fixed unused GetCharacterPhysicalPosition Made the server use the correct insert function Fixed position save Cleaned up code and removed the unnecessary SQL statement Moved Character Prepared Statement for Selecting position to the ConstructedStatement Get function Updated changelog
0653862
to
0fda5e0
Compare
AddPreparedStatement(CharacterPreparedStatement.CharacterSkillsSelect, "SELECT `skillId`, `skillStatus`, `skillPoints`, `skillXpSpent` FROM `character_skills` WHERE `id` = ?;", MySqlDbType.UInt32); | ||
AddPreparedStatement(CharacterPreparedStatement.CharacterStatsSelect, "SELECT `strength`, `strengthXpSpent`, `strengthRanks`, `endurance`, `enduranceXpSpent`, `enduranceRanks`, `coordination`, `coordinationXpSpent`, `coordinationRanks`, `quickness`, `quicknessXpSpent`, `quicknessRanks`, `focus`, `focusXpSpent`, `focusRanks`, `self`, `selfXpSpent`, `selfRanks`, `healthRanks`, `healthXpSpent`, `healthCurrent`, `staminaRanks`, `staminaXpSpent`, `staminaCurrent`, `manaRanks`, `manaXpSpent`, `manaCurrent` FROM `character_stats` WHERE `id` = ?;", MySqlDbType.UInt32); | ||
AddPreparedStatement(CharacterPreparedStatement.CharacterAppearanceSelect, "SELECT `eyes`, `nose`, `mouth`, `eyeColor`, `hairColor`, `hairStyle`, `hairHue`, `skinHue` FROM `character_appearance` WHERE `id` = ?;", MySqlDbType.UInt32); | ||
AddPreparedStatement(CharacterPreparedStatement.CharacterFriendsSelect, "SELECT cf.`friendId`, c.`name` FROM `character_friends` cf JOIN `character` c ON (cf.`friendId` = c.`guid`) WHERE cf.`id` = ?;", MySqlDbType.UInt32); | ||
|
||
AddPreparedStatement(CharacterPreparedStatement.CharacterPositionInsert, "REPLACE INTO character_position (id, cell, positionX, positionY, positionZ, rotationX, rotationY, rotationZ, rotationW) VALUES (?, ?, ?, ?, ?, ?, ? ,? ,?);", MySqlDbType.UInt32, MySqlDbType.UInt32, MySqlDbType.Float, MySqlDbType.Float, MySqlDbType.Float, MySqlDbType.Float, MySqlDbType.Float, MySqlDbType.Float, MySqlDbType.Float); | ||
ConstructStatement(CharacterPreparedStatement.CharacterPositionSelect, typeof(CharacterPosition), ConstructedStatementType.Get); |
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.
Converted Get and added the Insert/Update constructedstatements.
@@ -173,7 +223,11 @@ public bool IsNameAvailable(string name) | |||
|
|||
public async Task UpdateCharacter(Character character) | |||
{ | |||
ExecutePreparedStatement(CharacterPreparedStatement.CharacterPositionInsert, character.Id, character.Position.LandblockId.Raw, character.Position.Offset.X, character.Position.Offset.Y, character.Position.Offset.Z, character.Position.Facing.X, character.Position.Facing.Y, character.Position.Facing.Z, character.Position.Facing.W); | |||
// Save all of the player positions | |||
foreach(var pos in character.CharacterPositions) |
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.
This is a big hammer to save all during every save event.
CharacterPosition newCharacterPosition = new CharacterPosition(); | ||
if (result.Count > 0) | ||
{ | ||
newCharacterPosition.cell = result.Read<uint>(0, "cell"); |
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.
didn't want to use the ORM stuff here?
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.
That was updated from a previous slide; I've pushed a commit with updated ORM calls.
Source/ACE.Entity/Character.cs
Outdated
// initialize the blank character positions | ||
InitializeCharacterPositions(); | ||
CharacterPositions = new ReadOnlyDictionary<CharacterPositionType, CharacterPosition>(characterPositions); | ||
PhysicalPosition = new Position(CharacterPositions[CharacterPositionType.PhysicalLocation].cell, CharacterPositions[CharacterPositionType.PhysicalLocation].positionX, CharacterPositions[CharacterPositionType.PhysicalLocation].positionY, CharacterPositions[CharacterPositionType.PhysicalLocation].positionZ, CharacterPositions[CharacterPositionType.PhysicalLocation].rotationX, CharacterPositions[CharacterPositionType.PhysicalLocation].rotationY, CharacterPositions[CharacterPositionType.PhysicalLocation].rotationZ, CharacterPositions[CharacterPositionType.PhysicalLocation].rotationW); |
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.
seems like it would be helpful here to have a Position.Clone() method so that you didn't have to do this inline.
|
||
namespace ACE.Entity | ||
{ | ||
[DbTable("character_position")] |
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.
was using the existing one just not going to work?
@@ -0,0 +1,139 @@ | |||
namespace ACE.Entity.Enum | |||
{ | |||
public enum CharacterPositionType |
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 opposed to the other Positions enum? are they both needed?
Source/ACE/Entity/Player.cs
Outdated
/// <summary> | ||
/// Set's the tied lifestone for use casting the Lifestone Recall spell | ||
/// </summary> | ||
public void SetLifestoneTiedCharacterPosition(CharacterPosition newPosition) |
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.
It seems like we should have a single "SetPosition(Enum.Position positionType, Position position)" method so that we don't have to have 1 of these for each.
/// <summary> | ||
/// This function will save all of the CharacterPositions | ||
/// </summary> | ||
public void SaveCharacterPositions(Character character) |
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'm pretty sure we can just do 1-off saves when the player changes them. The only save that should be saved with the character is the physical position and maybe the last used portal. We can save the others when they tie/bind.
newStartingPosition.character_id = character.Id; | ||
newInvalidPosition.character_id = character.Id; | ||
character.SetCharacterPositions(CharacterPositionType.PhysicalLocation, CharacterPositionExtensions.StartingPosition); | ||
character.SetCharacterPositions(CharacterPositionType.LifestoneUsed, CharacterPositionExtensions.InvalidPosition); |
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 think these are really necessary. I'm OK with having "null" for Positions the character has never tied to.
ALTER TABLE `character_position` | ||
CHANGE COLUMN `id` `character_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' FIRST; | ||
ALTER TABLE `character_position` | ||
CHANGE COLUMN `positionType` `positionType` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `cell`, |
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.
change AFTER to BEFORE
ALTER `positionType` DROP DEFAULT; | ||
ALTER TABLE `character_position` | ||
CHANGE COLUMN `character_id` `character_id` INT(10) UNSIGNED NOT NULL FIRST, | ||
CHANGE COLUMN `positionType` `positionType` TINYINT(3) UNSIGNED NOT NULL AFTER `cell`; |
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.
change AFTER to BEFORE
@@ -260,12 +314,12 @@ public bool IsNameAvailable(string name) | |||
c.TemplateOption = result.Read<uint>(0, "templateOption"); | |||
c.StartArea = result.Read<uint>(0, "startArea"); | |||
|
|||
c.Position = await this.GetPosition(guid); | |||
c.PhysicalPosition = await this.GetPosition(guid); |
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.
Change PhysicalPosition to Location?
Character.Location = current position right?
|
||
#if DBDEBUG | ||
Console.WriteLine(types); | ||
Console.WriteLine(query); |
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.
Change to log.Debug ?
/// <summary> | ||
/// Allegiance hometown recall position | ||
/// </summary> | ||
AllegianceHometown = 0x06, |
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.
Source?
/// <summary> | ||
/// Mansion recall position | ||
/// </summary> | ||
MansionRecall = 0x07 |
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.
Source?
Source/ACE/Entity/Player.cs
Outdated
// TODO : Save the Mansion Recall position information from the destination of a house box | ||
character.SetCharacterPositions(CharacterPositionType.MansionRecall, newPosition); | ||
} | ||
|
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.
Not sure we'd set Allegiance Hometown and Mansion Recall positions to each character.. Mansion recall is essentially a copy of monarch's house recall if house is a villa or mansion, otherwise it didn't work or errored, not sure what it did here. I assume it would be a check if character is in allegiance, followed by confirming house type, then execution or returning error.
Hometown recall might be stored in the allegiance information somewhere, i haven't seen it yet however.
@@ -132,6 +132,7 @@ public static void CharacterRestore(ClientPacketFragment fragment, Session sessi | |||
uint lowGuid = DatabaseManager.Character.GetMaxId(); | |||
character.Id = lowGuid; | |||
character.AccountId = session.Id; | |||
character.DateOfBirth = character.CreationTimeStamp.ToString(); |
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.
check /birth command, I'm thinking this property was the same output
@@ -0,0 +1,2 @@ | |||
ALTER TABLE `character_position` | |||
ADD COLUMN `positionType` TINYINT UNSIGNED NULL DEFAULT '0' AFTER `cell`; |
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.
change AFTER to BEFORE
be3bb01
to
63df763
Compare
I am going to close this PR, untill I work the Positions and CharacterPositions in too the same object and the code ready for another look. Thanks For your reviews so far! |
This huge PR is related to Issue #166. The code has been changed to allow more then one position type. A class was added for Character position types that match the requirements listed in the issue. A secondary Position Type class was added to match the client, provided by @LtRipley36706.
To work with the ORM code introduced during the developer meeting, I've attempted to copy the pseudo 1:1 mapping into
CharacterPosition.cs
. In order to allow for more then one position, theCharacter.Position
member was changed to dictionary containing a list of character positions by type.Player.Position
was changed toPlayer.PhysicalPosition
and when the server decides to save the positions to the database, the data is saved through the ORM object inCharacterPosition.cs
.There were a few things left to do, that were not accomplished for Issue #166:
ChangeLog:
CharacterPostion
andCharacterPositionType
classes to store the Database types requested in Issue Give Characters a set of positions #166.CharacterPostion
ORM logic.StartingLocation
, until we pull from the database. Also included an Invalid location as a default (0).character_positions
table and AddedpositionType
column.positionType
column.positionType
to required Critera forcharacter_positions
.CharacterPositionInsert
andCharacterPositionUpdate
to the Character Database.CharacterPositionInsert
andCharacterPositionUpdate
prepared SQL statements by utilizing theConstructStatement
function.positionType
clause to theCharacterPositionSelect
prepared statement.CharacterPositionType
.CharacterPostion
from the database, requires a character Id andCharacterPositionType
.CharacterPositionSelect
prepared statement to aConstructStatement
.GitLog: