Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Private Server
You last visited: Today at 00:31

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



weird monster movement!

Discussion on weird monster movement! within the CO2 Private Server forum part of the Conquer Online 2 category.

Closed Thread
 
Old   #1
 
Mr_PoP's Avatar
 
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?

Mr_PoP is offline  
Old 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.
pro4never is offline  
Old 01/16/2013, 15:14   #3
 
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 329
*
go for it is offline  
Old 01/16/2013, 19:58   #4
 
Mr_PoP's Avatar
 
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!!!
Mr_PoP is offline  
Old 01/17/2013, 02:48   #5
 
{ Angelius }'s Avatar
 
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() < || 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.XMonster.YMonster.Target.XMonster.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.MoveSpeedmob.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 :|
{ Angelius } is offline  
Old 01/17/2013, 08:58   #6
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by { Angelius } View Post
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() < || 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.XMonster.YMonster.Target.XMonster.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.MoveSpeedmob.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
Mr_PoP is offline  
Old 01/17/2013, 11:27   #7
 
{ Angelius }'s Avatar
 
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
{ Angelius } is offline  
Old 01/17/2013, 13:46   #8
 
Mr_PoP's Avatar
 
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
Mr_PoP is offline  
Thanks
1 User
Old 01/17/2013, 14:41   #9
 
shadowman123's Avatar
 
elite*gold: 0
Join Date: Aug 2007
Posts: 1,525
Received Thanks: 230
Am glad for u .. good luck
shadowman123 is offline  
Old 01/17/2013, 22:50   #10
 
JohnHeatz's Avatar
 
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
JohnHeatz is offline  
Closed Thread


Similar Threads 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.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.