Skip to content
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

Add Cow object #482

Merged
merged 21 commits into from
Aug 6, 2017
Merged

Conversation

LtRipley36706
Copy link
Member

@LtRipley36706 LtRipley36706 commented Jul 31, 2017

  • NOTE: The following changes require ACE-World database v0.1.8 or newer...
  • Added NpcLooksLikeObject check for Creature assessment profile fix provided by @OptimShi.
  • Moved Default do nothing UseDone to WorldObject and removed it from GenericObject.
  • Added Cow weenie object.
  • Added Cow, Creature, and Container to the WorldObjectFactory.
  • Say Hi to the cow in Holtburg.

@ogmage78
Copy link
Contributor

I know we discussed this a while back. Are we going to do one of these per creature family? By that I mean all Tuskers for example will be one object not an object for every different tusker? I think if we do this by weenietype and not weenie - that will allow content creators to add content without having to change server code.

@LtRipley36706
Copy link
Member Author

No need. Cows were a unique WeenieType, all other creatures will simply be Creature.cs

@ddevec
Copy link
Contributor

ddevec commented Jul 31, 2017

Monster.cs? Monsters have different logical behaviors than creatures (e.g. players don't have scripts they run to attack nearby players).

At least, not on the server side :-P

@LtRipley36706
Copy link
Member Author

LtRipley36706 commented Jul 31, 2017

There's no distinction between Monsters and Creatures in the client, it would seem from turbine's viewpoint , we all sprang from creature weenietype, at least that i've seen, in the terms of weenie objects used to control actions

Copy link
Contributor

@Mogwai-TheFurry Mogwai-TheFurry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, you have a LOT of chunks of code you added that are just big comment blocks. Clean them up, please.

{
var criteria = new Dictionary<string, object> { { "aceObjectId", aceObjectId } };
var objects = ExecuteConstructedGetListStatement<WorldPreparedStatement, AceObjectPropertiesSkill>(WorldPreparedStatement.GetAceObjectPropertiesSkills, criteria);
////objects.ForEach(o =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to include chunks of commented code in new stuff.

: base(aceObject, guid)
{
}
////public Creature(AceObject aceObject, ObjectGuid guid)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deletes are preferred over comments. We have history.

: base(guid, aceObject)
{
}
////public GenericObject(ObjectGuid guid, AceObject aceObject)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point the class serves no purpose. It's a commented out class with a constructor. Just remove it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public static WorldObject CreateWorldObject(AceObject aceO)
        {
            WeenieType objWeenieType = (WeenieType?)aceO.WeenieType ?? WeenieType.Generic;

            switch (objWeenieType)
            {
                case WeenieType.LifeStone:
                    return new Lifestone(aceO);
                case WeenieType.Door:
                    return new Door(aceO);
                case WeenieType.Portal:
                    return new Portal(aceO);
                // case WeenieType.PKModifier:
                //    return new PKModifier(aceO);
                case WeenieType.Cow:
                    return new Cow(aceO);
                case WeenieType.Creature:
                    return new Creature(aceO);
                case WeenieType.Container:
                    return new Container(aceO);
                default:
                    return new GenericObject(aceO);
            }
        }

Need a default object. I assume this object will eventually have some worth while code in it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather it echo out something to the effect of "Was asked to create a {WeenieType}, but don't know how" or something. GenericObject is useless Object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except, there are many WeenieType.Generic objects in the database.. its not going to be as useless as you are suggesting

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, removing it kills every spawn-able object not explicitly handled by CreateWorldObject which does us no good in the now.

Copy link
Contributor

@ddevec ddevec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of minor nits.

@@ -39,7 +39,10 @@ private enum WorldPreparedStatement
GetAceObjectPropertiesPosition = 24,
GetAceObjectPropertiesSpell = 25,
GetAceObjectGeneratorLinks = 26,
GetMaxId = 27
GetMaxId = 27,
GetAceObjectPropertiesAttributes,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the inconsistency here. Either remove the = # from all of them, or put the = # in your enum values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Og's PR removes them all, I only added new ones from Shard and did not include numbers

//// return;
////}

if (playerDistanceTo >= radiusSquared)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that you have to do it here, but this code appears common to most/all HandleActionOnUse functions. Perhaps we should come up with some other solution than copying it all over the place?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a reasonable suggestion, it probably will be in at least a few more objects as well

Copy link
Contributor

@ddevec ddevec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few code smells creeping in your last set of commits. Nothing major.

ret.StringProperties.ForEach(c => c.AceObjectId = guid);
ret.GeneratorLinks.ForEach(c => c.AceObjectId = guid);

// We're not seemingly changing the guids for the Dictionaries below from Clone(), is this bad?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dictionaries separate the DB layer data and the in-game data, so the guid doesn't need to be adjusted (it will be crated/adjusted on save). This is an okay note, but the comments below it are just clutter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ddevec you and @Mogwai-TheFurry need to talk. When we clone a new object from a weenie, we have to do a deep reset of those values. I don't care where it takes place, but it has to happen prior to save. I have this in my code. I made it part of the clone new method. It happens behind the scenes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general I dislike the fact that save-time data creeps into our live data-structures, and the smell here is associated with the presence of the redundant data. I believe either implementing the guid update at clone time (as Ripley has done here), or at save time is sufficient. Other than the fact I don't like this data existing at all, I think Ripley's implementation here is fine.

It looks like you and Ripley have essentially created the same code to accomplish this, and it seems to be a fine way to go about doing it to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied his code in per other discussions just to make it clear what the guid code was doing

session.Network.EnqueueSend(new GameMessagePutObjectInContainer(session, session.Player.Guid, loot, 0),
new GameMessageUpdateInstanceId(loot.Guid, session.Player.Guid, PropertyInstanceId.Container));
}
WorldObject loot = WorldObjectFactory.CreateNewWorldObject(weenieId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed this modifies the player's inventory outside fo an actionchain. This is a race. Please throw a FIXME comment in there for me, since your modifying that code anyway (or wrap this chunk of code in an actionchain).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this code moves to Player (eventually Admin) class anyway

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likely most of these commands will need actionchains and relocation.. fwiw

@@ -104,10 +104,13 @@ public Landblock(LandblockId id)
var factoryObjects = WorldObjectFactory.CreateWorldObjects(objects);
factoryObjects.ForEach(fo =>
{
if (!worldObjects.ContainsKey(fo.Guid))
if (fo != null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what instance will WorldObjectFactory.CreateWorldObjects populate its object list with a null, and why is that not a bug in WorldObjectFactory.CreateWorldObjects?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically impossible in the current state of the code. I added the null check when while I was temping in the removal of GenericObject to reconfirm what I already knew. WOF.CreateWorldObjects prevents nulls in results now so the fo null check is just not possible to hit ever, and technically so is the null in CreateWorldObjects as long as we set a default object, which I see no reason no to do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its important to decide if a correct implementation of CreateWorldObjects can or cannot introduce null objects into its list. As it returns a list, I would imagine cannot is the correct behavior.

I am a strong opponent of error-oblivious computing (intentionally ignoring errors), it leads to buggy, inconsistent, and difficult to debug code. Intentionally ignoring values that should be impossible from CreateWorldObjects is a form of error-oblivious computing.

With that said, I would highly recommend removing this check, either replace it with an assertion (Debug.Assert) if your worried about null values, or remove it entirely.

As written, this code indicates CreateWorldObjects can/should return null values in its list, and that's just confusing.

@LtRipley36706 LtRipley36706 merged commit 65fbd37 into ACEmulator:master Aug 6, 2017
@LtRipley36706 LtRipley36706 deleted the dev-CowTipping branch February 10, 2018 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants