|
You last visited: Today at 00:31
Advertisement
weird monster movement!
Discussion on weird monster movement! within the CO2 Private Server forum part of the Conquer Online 2 category.
01/15/2013, 16:25
|
#1
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
weird monster movement!
anyclue why the mobs might move like it do in the video?
|
|
|
01/16/2013, 04:53
|
#2
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,380
|
Because that's how their artificial intelligence was written.
What source is this part of?
Couple things.
#1: Looks like they are all running based on a movement thread. This means that all mobs on server move once every say... 800 ms. This means they all move at exactly the same time.
#2: The pathfinding is pretty poor as they all just kinda clump towards the target. Bit difficult to tell how good or bad the pathfinding is though without first correcting the timing issue.
|
|
|
01/16/2013, 15:14
|
#3
|
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 329
|
*
|
|
|
01/16/2013, 19:58
|
#4
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
it's my own source made it from scratch , and it's a timer thread, which loop every 1sec through an ActiveMonsters(those mobs that being activated when a Hero is around it), if the Mob has a target ,and that target away from the Mob , but within it's walkable range it calls this Method Move()
Code:
private void Move(IMonster mob) {
if(DateTime.Now >= mob.Timers.LastMovment.AddMilliseconds(mob.Monstertype.MoveSpeed)) {
mob.Timers.LastMovment = DateTime.Now;
if(mob.Path == null) return;
foreach(var loc in mob.Path) {
if(mob.IsDead) return;
var dir = Calculations.GetDirection(mob.Location.X, mob.Location.Y, loc.X, loc.Y);
world.Entities.BattleEntities.Move(mob, Common.MoveType.Run, (x) => {
if(world.DMaps[x.Map].Cells[loc.X, loc.Y].Walkable) {
x.Direction = dir;
world.DMaps[x.Map].Cells[x.Location.X, x.Location.Y].Walkable = true;
x.Location = loc;
world.DMaps[x.Map].Cells[loc.X, loc.Y].Walkable = false;
mob.Path.Remove(loc);
} else {
mob.Target = null;
}
return true;
});
return;
}
}
}
I can't see , what is wrong here ?, since every Mob has a check on it's movement speed , so they are not moving at the same time but one after the another towards the target!
EDIT: this weird movement does not occur all the time , it does from time to time , sometimes it never occurs!!!
|
|
|
01/17/2013, 02:48
|
#5
|
elite*gold: 0
Join Date: Aug 2010
Posts: 992
Received Thanks: 1,110
|
PHP Code:
while(true) { foreach(var Monster in ActiveMonsters.ReturnCopy())//ReturnCopy = thread safe { if(Monster.IsDead) continue; if(DateTime.Now < Monster.Timers.LastMovment) continue; if (Monster.PathFinding) { if (Monster.Path.Count() < 1 || Monster.Target == null) { Monster.PathFinding = false; continue; } //Get the next X/Y from the path list and walk/Remove the X/Y from the path list } else { if (Monster.Target == null) { continue; } Monster.Path = GetPath(Monster.X, Monster.Y, Monster.Target.X, Monster.Target.Y); if (Monster.Path.Count() < 1) continue; //Get the next X/Y from the path list and walk/Remove the X/Y from the path list } Monster.Timers.LastMovment = DateTime.Now.AddMilliseconds(Random.Next(mob.Monstertype.MoveSpeed, mob.Monstertype.MoveSpeed + 400))
}
Your Pathfinder should check every X/Y and make sure its valid before adding it to the path list and inside the movement thread you only check to make sure no player is standing in the next X/Y that you are about to move the monster to and if there is a player then you clear the path list and try to get a fresh path if needed...
And what i don't understand is if a timer/thread are executing the Move() void then whats getting the Mob.Path? a different thread ?
And before you allow the monsters to attack the target you should check and make sure that at least 300 MS or so has passed since the last jump or else monsters wold attack the target while he is still in the air and change directions as soon as you make a jump
mob.Timers.LastMovment = DateTime.Now; should be right before the return and not in the top of the void
mob.Target = null; Target should never = null unless the target had left the monster screen and should not depend on the monster view range/attack range
And to me it sounds like
A. Monsters are being controlled by more then 1 thread/timer IE: Move() void is being called randomly from the same/different threads so try and use something like the while loop i posted and see if eliminates the problem
B. You are not sending a valid Direction in the walk packet so spawn 1 Pheasant in twin city.. break point at the top of your monsters thread and track his movements based on the direction and how your loop handles it..
C. Monsters X/Y are not really being updated upon walking and the same process in step B can prove if its being updated or no
Good luck buddy...
Edit: I thought you stopped working on your server :|
|
|
|
01/17/2013, 08:58
|
#6
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
Quote:
Originally Posted by { Angelius }
PHP Code:
while(true) { foreach(var Monster in ActiveMonsters.ReturnCopy())//ReturnCopy = thread safe { if(Monster.IsDead) continue; if(DateTime.Now < Monster.Timers.LastMovment) continue; if (Monster.PathFinding) { if (Monster.Path.Count() < 1 || Monster.Target == null) { Monster.PathFinding = false; continue; } //Get the next X/Y from the path list and walk/Remove the X/Y from the path list } else { if (Monster.Target == null) { continue; } Monster.Path = GetPath(Monster.X, Monster.Y, Monster.Target.X, Monster.Target.Y); if (Monster.Path.Count() < 1) continue; //Get the next X/Y from the path list and walk/Remove the X/Y from the path list } Monster.Timers.LastMovment = DateTime.Now.AddMilliseconds(Random.Next(mob.Monstertype.MoveSpeed, mob.Monstertype.MoveSpeed + 400))
}
Your Pathfinder should check every X/Y and make sure its valid before adding it to the path list and inside the movement thread you only check to make sure no player is standing in the next X/Y that you are about to move the monster to and if there is a player then you clear the path list and try to get a fresh path if needed...
And what i don't understand is if a timer/thread are executing the Move() void then whats getting the Mob.Path? a different thread ?
And before you allow the monsters to attack the target you should check and make sure that at least 300 MS or so has passed since the last jump or else monsters wold attack the target while he is still in the air and change directions as soon as you make a jump
mob.Timers.LastMovment = DateTime.Now; should be right before the return and not in the top of the void
mob.Target = null; Target should never = null unless the target had left the monster screen and should not depend on the monster view range/attack range
And to me it sounds like
A. Monsters are being controlled by more then 1 thread/timer IE: Move() void is being called randomly from the same/different threads so try and use something like the while loop i posted and see if eliminates the problem
B. You are not sending a valid Direction in the walk packet so spawn 1 Pheasant in twin city.. break point at the top of your monsters thread and track his movements based on the direction and how your loop handles it..
C. Monsters X/Y are not really being updated upon walking and the same process in step B can prove if its being updated or no
Good luck buddy...
Edit: I thought you stopped working on your server :|
|
am doing everything you said, Move() being called from the same thread MonsterAction occurs let me make it more clear by posting the MonsterAction()
Code:
private void MonsterAction() {
while (true) {
foreach (var monster in world.Entities.BattleEntities.ActiveMonsters.Values) {
#region Guard
if (monster.IsGuard) {
if (DateTime.Now >= monster.Timers.LastAttack.AddSeconds(4)) {
var nearest = world.Entities.Indexer[monster];
foreach (var mon in nearest) {
if (mon as IMonster != null) {
var mob = mon as IMonster;
if (mob.IsDead) continue;
if (!mob.IsGuard && Calculations.Distance(monster.Location.X, monster.Location.Y, mob.Location.X, mob.Location.Y) <= monster.Monstertype.AttackRange) {
world.Entities.BattleEntities.NotifyMagic(monster, mob.EntityID, mob.Location.X, mob.Location.Y, world.Entities.Database.SkillsManager.GetMagicTypeByIdAndLevel((ushort)monster.Monstertype.MagicType, 0), 24, 0, 0);
monster.Timers.LastAttack = DateTime.Now;
break;
}
} else if (mon as IHero != null) {
var hero = mon as IHero;
if (hero.IsDead) continue;
if (hero.ShortFlags.HasFlag(ShortStatusFlags.FlashName) || hero.ShortFlags.HasFlag(ShortStatusFlags.BlackName)) {
world.Entities.BattleEntities.NotifyMagic(monster, hero.EntityID, hero.Location.X, hero.Location.Y, world.Entities.Database.SkillsManager.GetMagicTypeByIdAndLevel((ushort)monster.Monstertype.MagicType, 0), 24, 0, 0);
monster.Timers.LastAttack = DateTime.Now;
break;
}
}
}
} else continue;
}
#endregion
#region NormalMonster
else {
if (monster.Path == null || monster.Target == null) {
if (monster.PathTries >= 64) {
monster.PathTries = 0;
monster.Path = null;
monster.Target = null;
world.Entities.BattleEntities.ActiveMonsters.TryRemove(monster.EntityID, out tempMonster);
continue;
}
var near = world.Entities.Indexer[monster].Where(x => x is IHero).Cast<IHero>().Where(x => Calculations.Distance(x.Location.X, x.Location.Y, monster.Location.X, monster.Location.Y) <= monster.Monstertype.ViewRange && !x.IsDead);
if (near.Count() > 0) hero = near.OrderBy(x => Calculations.Distance(x.Location.X, x.Location.Y, monster.Location.X, monster.Location.Y)).First(); else hero = null;
if (hero == null && monster.BirthLocation.Equals(monster.Location)) {
world.Entities.BattleEntities.ActiveMonsters.TryRemove(monster.EntityID, out tempMonster);
continue;
} else if (hero == null && monster.Path == null) {
monster.Path = world.DMaps[monster.Map].PathFinder.FindPath(monster.Location, monster.BirthLocation);
monster.Target = monster;
monster.PathTries++;
continue;
}
monster.Target = hero;
monster.Path = world.DMaps[monster.Map].PathFinder.FindPath(monster.Location, hero.Location);
monster.PathTries++;
}
if (Calculations.Distance(monster.Location.X, monster.Location.Y, monster.Target.Location.X, monster.Target.Location.Y) != 1) {
Move(monster);
} else {
if (monster.Target.Equals(monster)) {
world.Entities.BattleEntities.ActiveMonsters.TryRemove(monster.EntityID, out tempMonster);
} else {
if (monster.Monstertype.MagicType == 0 && !monster.IsDead) {
world.Entities.BattleEntities.NotifyMelee(monster, monster.Target);
} else {
world.Entities.BattleEntities.NotifyMagic(monster, monster.Target.EntityID, monster.Target.Location.X, monster.Target.Location.Y, world.Entities.Database.SkillsManager.GetMagicTypeByIdAndLevel((ushort)monster.Monstertype.MagicType, 0), (uint)24, 0, 0);
}
continue;
}
}
if (monster.Path != null) {
if (monster.Target == null || monster.Location.Equals(monster.BirthLocation) || monster.Path.Count == 0) {
monster.Target = null;
monster.Path = null;
}
}
}
#endregion
}
Thread.Sleep(1000);
}
}
so idk what is wrong :\
PS: I DID STOP WORKING ON IT :- I just finished exams was bored , so I tried to fix this shitty bug
|
|
|
01/17/2013, 11:27
|
#7
|
elite*gold: 0
Join Date: Aug 2010
Posts: 992
Received Thanks: 1,110
|
Assuming the foreach (var loc in mob.Path) is not breaking after processing the first location and its looping through all the items in the collection try to get rid of it and replace it with something like
var loc = mob.Path.First(); or var loc = mob.Path.Last(); depends on the mob.Path collection type
And Thread.Sleep(1000); with Thread.Sleep(1); as monsters wont be waiting a second to move again
|
|
|
01/17/2013, 13:46
|
#8
|
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
|
thanks guys for your replies , I have fixed the issue , it was never my AI or how am handling mobs , it was the stupid client , it was requesting GeneralData with Subtype->( EntityReSpawn = 102) , that was causing the issue , coz when the mob is walking , and client request to respwan it, it looks like that , so I just removed the handling or respawning and it worked fine , I never needed it anyways
|
|
|
01/17/2013, 14:41
|
#9
|
elite*gold: 0
Join Date: Aug 2007
Posts: 1,525
Received Thanks: 230
|
Am glad for u .. good luck
|
|
|
01/17/2013, 22:50
|
#10
|
elite*gold: 150
Join Date: Apr 2010
Posts: 9,739
Received Thanks: 8,981
|
As this issue has been resolved, and the fix for it has even been posted, I'd guess you won't be mad if I close it
|
|
|
 |
Similar Threads
|
NEED licence movement
10/04/2012 - Browsergames Trading - 3 Replies
I need licence movement for 1.9 dollars paypal or 1.4 euro neteller, so if any reseller want just answer me
|
Weird.... Just weird ( inside )
08/05/2011 - Shaiya Private Server - 14 Replies
Windows 2008 webserver S2 , service pack 4 , 64 bit Os. when i go to install Sql 2005 it does its little pre install check list, well i get a warning on asp.net , it tells me that 64 bit is installed and mysql report services require 32 bit.. So i sorta stumble around a bit, well i ran across Banes tut on sql 2008 , so i thought allright lets try it. as i click on the installserver.bat for the client,, the cmd prompt comes up, goes thew it steps, then tells me that Shaiya is not...
|
Entity Movement
06/15/2011 - CO2 Programming - 6 Replies
These are the results from a quick sniffing session:
; west (x--, y++)
18 00 15 27 71 00 00 00 XX XX XX XX 01 00 00 00 DF 8D 47 04 00 00 00 00
; north west (x--)
18 00 15 27 22 00 00 00 XX XX XX XX 01 00 00 00 D5 01 48 04 00 00 00 00
; north (x--, y--)
18 00 15 27 03 00 00 00 XX XX XX XX 01 00 00 00 ED A6 48 04 00 00 00 00
|
The most epic Grand Chase Cheat Engine hack ever (EXP/monster movement and spawn hak)
10/23/2009 - Grand Chase - 2 Replies
I thought this was just the coolest hack ever. The only hint given by creator was taht you need to find out waht makes monsters stop and go and then use that value and repeat it.
Monster Spawn/Time hack:
YouTube - Grand chase hack - Time Hack
Monster Spawn hack used to get exp:
YouTube - EXP Spawn Hack Grand chase :D
|
3d movement? how?
06/21/2009 - General Coding - 7 Replies
Hi guys,
Well, i can use...
1. Autoscript
2. a packet bot
3. direct ingame manipulation ( the way i wanna try )
Any method has its benefits.
1.
|
All times are GMT +1. The time now is 00:34.
|
|