you need to check to make sure that the target is actual a SimpleArtifact before you make that cast.
CODE
if(target is SimpleArtifact && ((SimpleArtifact)target).Name == "DEMISE")
Another note (unrelated to the crash) is that this code
CODE
if (so.OccupantType == typeof(JimsRuby)) hasaugment1 = true; if (so.OccupantType == typeof(JimsRuby)) hasaugment2 = true; if (so.OccupantType == typeof(JimsRuby)) hasaugment3 = true; if (so.OccupantType == typeof(JimsRuby)) hasaugment4 = true;
is really designed to work when you have different augments for each test. If you repeat the same augment type in those tests, then just adding one JimsRuby will satisfy all of the tests in one shot. I'm guessing that you just put that in for testing, but if you actually plan on having the same augment in multiple slots, then you will need to change that code.
slida- 05-22-2006
Well that wasn't the problem. Changed it up and same results. It will goes as far as making the augment sound effect before it crashes. It's that null object reference. Thats why I was thinking I had to make an instance of JimsRuby to refer to or something like that.
CODE
XmlSockets s = (XmlSockets)XmlAttach.FindAttachment(target, typeof(XmlSockets));
maybe it's here?
Also the first thing I did earlier was hash out the augment checks when it crashed. It no longer crashed but the statue wouldn't augment. Maybe because I needed to change the check like you suggested.
Ok I hashed out this code, and changed the return value to true so it would augment and no crash.
ArteGordon- 05-22-2006
ah, sorry. This is the problem
QUOTE
foreach (XmlSockets.SocketOccupant so in s.SocketOccupants) { if(so == null) continue;
if (so.OccupantType == typeof(JimsRuby)) hasaugment1 = true; if (so.OccupantType == typeof(JimsRuby)) hasaugment2 = true; if (so.OccupantType == typeof(JimsRuby)) hasaugment3 = true; if (so.OccupantType == typeof(JimsRuby)) hasaugment4 = true;
}
slida- 05-22-2006
Ok, all systems go! I won't be working on this for a few days so no hurry on these next questions.
Now that I see how it works, I want to make the order matter as well as the augments, and also I'd like to make it so you can just remove the augments that are in the wrong place and put them somewhere else. I'm thinking as I write this that maybe using the combination lock might be an easier way to accomplish this, what do you think? Can these ideas be combined in some way to make the coding easier?
Thanks for your help again, sorry to be so high-maintenance.
ArteGordon- 05-23-2006
to test the order, I would change this code to something like
CODE
for (int i = 0; i<s.SocketOccupants.Count; i++)
{ XmlSockets.SocketOccupant so = (XmlSockets.SocketOccupant)s.SocketOccupants[i];
if(so == null) continue;
if (so.OccupantType == typeof(JimsRuby) && i ==0) hasaugment1 = true; if (so.OccupantType == typeof(JimsRuby) && i == 1) hasaugment2 = true; if (so.OccupantType == typeof(JimsRuby) && i == 2) hasaugment3 = true; if (so.OccupantType == typeof(JimsRuby) && i == 3) hasaugment4 = true;
}
that will test for the occupants in specific slots.
To allow the augments to be removed by adding overrides for the CanRecover and OnRecover methods.
CODE
public override bool CanRecover(Mobile from, object target, int version) { return true; }
public override bool OnRecover(Mobile from, object target, int version) { return true; }
That will allow the augment to be recovered. To actually recover them will require the use of an item like the HammerOfRecovery.
slida- 05-27-2006
Ok I've got some follow up here. I thought about the problem for a few days, and came up with an idea, the problem being recovering augments that are in the wrong spot, but not being able to recover the ones in the right spot. I would like to do something even fancier but it seems like overkill(do you know anything about the game called Mastermind?). The reason I want to do it this way is there are 24 different possible combinations if I create only 4 different augments and even more if I create more than four. Thats a lot of frustration for someone playing. However if I can do something like this, as soon as you get an augment in the right place, it stays there, thus paring down possible choices. I also would like to avoid using another item to accomplish this. Since I am basically just using the skeleton of XmlSockets and nothing is really being 'augmented', I though I could perhaps not worry about the OnRecover and CanRecover methods and do something like this.
CODE
If (so.OccupantType == typeof(JimsRuby) && i == 0) hasaugment1=true; else (on single or double click delete the augment and create a new instance in the players backpack)
I took a shot at this by looking at other scripts and trying stuff but no dice. I'm not even sure if this is feasible. Any ideas?
I also just thought that an alternate way would be to do the slot checks in the CanAugment method, can you check what number the slot is when it's empty?
CODE
If (target is my artifact && slot is slot 0) { return true; } return false;
ArteGordon- 05-27-2006
interesting idea. Currently, the CanAugment method does not include the socket number being augmented, but I added a few simple mods that will allow you to override a new overloaded CanAugment method that does include that argument.
public override bool CanAugment(Mobile from, object target, int socketnumber)
Just replace the BaseSocketAugmentation.cs and XmlSockets.cs scripts with the ones attached.
slida- 05-28-2006
Allright, thanks Arte! That worked like a charm on the first try. I can finally move on to the next thing I have no idea how to do
slida- 05-28-2006
Well guess who spoke too soon? I tried both of your suggestions for checking the sockets for type to spawn the demon, and they worked when I just had the one augment JimsRuby, but when I made the rest it didn't work, nothing happened.
I looked at your scripts and tried to overload the OnAugment method so it also had a value for socketnumber so I could check for type and socketnumber, and it compiled fine so I guess I did that right but still nothing happened. What I realize now is I no longer have to check for augment types during OnAugment I just have to check if all the sockets are all filled but I still don't know how to do that. Here's the last thing I tried.
CODE
public override bool OnAugment(Mobile from, object target, int socketnumber) {
if(target is SimpleArtifact && ((SimpleArtifact)target).Name == "DEMISE")
{ // look for the other augments in the target sockets
XmlSockets s = ((XmlSockets)XmlAttach.FindAttachment(target, typeof(XmlSockets)));
if (hasaugment1 && hasaugment2 && hasaugment3 && hasaugment4) { Mobile m = new Daemon(); m.MoveToWorld(from.Location,from.Map); } } }
return true; }
ArteGordon- 05-28-2006
I think that you just want to check the occupants using this approach that I posted earlier. I dont think that you actually need the socketnumber argument unless you actually want to know what was just added.
CODE
for (int i = 0; i<s.SocketOccupants.Count; i++)
{ XmlSockets.SocketOccupant so = (XmlSockets.SocketOccupant)s.SocketOccupants[i];
if(so == null) continue;
if (so.OccupantType == typeof(JimsSkull) && i ==0) hasaugment1 = true; if (so.OccupantType == typeof(JimsRuby) && i == 1) hasaugment2 = true; if (so.OccupantType == typeof(JimsEmerald) && i == 2) hasaugment3 = true; if (so.OccupantType == typeof(JimsCrystal) && i == 3) hasaugment4 = true;
}
slida- 05-28-2006
I'll give this a try tomorrow, but I think that I already did this, and nothing happened, but I could have easily made a mistake, perhaps i didn't change the code in all of them.
What I'm thinking right now though is that so.OccupantType is going to be the same type, that which was just added, in every if statement. So how this is supposed to work is that it loops through the if statements for each socket, right? So each time it goes through a hasaugment value will be switched to true if the augment is there. It seems like so.OccupantType is not changing to another type when it goes through the loop.
This is a preemptive idea here, it may work just fine when I do it tomorrow.
Also, in what may end up being the real problem, when I think about it, I've been replacing the
CODE
foreach (XmlSockets.SocketOccupant so in s.SocketOccupants)
with
CODE
for (int i = 0; i<s.SocketOccupants.Count; i++)
{ XmlSockets.SocketOccupant so = (XmlSockets.SocketOccupant)s.SocketOccupants[i];
because I thought they were replacing each other. hmmm... maybe thats it.
ArteGordon- 05-29-2006
yes, you want to replace the forearch with the for loop. That way you can use the array index as the slot number to test for the specific augment in a specific position.
slida- 05-29-2006
yeah this doesn't work, I think that so.occupanType stays the same in every loop...or
Oh wait I just thought of something, I think the order matters, and is different for each augment because 'i' doesn't actually refer to a socket , its just a counter, So.OccupantType ends up not matching up with its numerical counterpart during the loop. I was also thinking it might be easier just to check to see if the last socket has been filled because the CanAugment forces you into correct order now. TIA!
slida- 05-31-2006
Is there a way to write what So.occupantTypes is to a text file when it does the conditional? Because the code isn't working and I can't tell why really.