ID:151220
 
Ok, I got a blob dude that attacks your main guy, the problem is that when I run it, my character thinks and walks by himself! I can control him, but he also controls himself and follows (and attacks) other characters without me telling him to, can anyone help?
Thanks, Gilser
Did you make the attack code in the main part of the mob code? If you did then your player may be inhariting the attack proccess.

Just a thought. Can't tell without seeing your code.
In response to karver
Just a thought. Can't tell without seeing your code.

Should I post it?
In response to Gilser
On 2/16/01 8:10 pm Gilser wrote:
Just a thought. Can't tell without seeing your code.

Should I post it?

Sure.
In response to karver
On 2/16/01 8:17 pm Karver wrote:
On 2/16/01 8:10 pm Gilser wrote:
Just a thought. Can't tell without seeing your code.

Should I post it?

Sure.

//moods (control automatic combat behavior)
#define WARY -1 //maintain a short distance
#define CALM 0 //defend if necessary
#define ASSERTIVE 1 //if attacked, seek revenge
#define HOSTILE 2 //attack first, ask questions later

//stepping modes or stances (control automatic motion)
#define SIT_STEP -1 //sitting
#define NO_STEP 0 //standing still
#define TRACK_STEP 1 //tracking something
#define RAND_STEP 2 //explore randomly
#define WALK_STEP 3 //move in a direction until there is a choice

mob/var
life = 50 //vital energy
name = "HP"
strength = 1 //damaging power
iq = 1 //mental power
aim = 1 //weapon skill
name = "sight"
armor = 1 //armor skill
immunity = 0 //parasite resistance
offense = 1 //damage multiplier
name = "attack"
defense = 1 //damage divisor
dexterity = 1 //attacking speed

//maximums are initialized in New()
max_life
max_strength
max_iq
max_aim
max_armor
max_immunity

karma //reincarnation penalty
parasites[] //list of parasites

step_mode=NO_STEP //NO_STEP,TRACK_STEP,RAND_STEP,WALK_STEP
step_lag = 10 //delay between steps
swing_lag = 60 //delay between swings

corpse //type of corpse to leave behind
rand_items //upper bound of random treasure items

mood=ASSERTIVE //(CHICKEN,WARY,CALM,ASSERTIVE,HOSTILE)

tmp
rank=1 //-1,0,1
party_id //mob type or mob id

mob/step_trg //target for TRACK_STEP
mob/enemy


mob/proc
Tick()
Swing()
OneSwing(target,aim,offense)
Peace()
War(attacker)
SeeWar(attacker,defender)

Die()
GotoAfterlife()

AddLife(N)
AddStrength(N)
AddIQ(N)
AddAim(N)
AddArmor(N)
AddImmunity(N)
AddKarma(N)

SetName(NewName)
ChangePartyLeader(group_id,default_leader)
MoveNoBump(Loc)
MoveNear(Loc)

Answer(Text)

AddParasite(P)
RemoveParasite(P)

StepAway(trg,dist)
StepTo(trg,dist)
StepRand()
StepExplore()


turf/proc
Use()
DontExplore()
DeltaZOnUse() //returns amount z will change if turf is used (for following down stairs)


area/Afterlife
name = "Chamber of the Dead"
desc = "Brrr. It's dead cold in here!"

Enter(mob/M)
if(usr && usr.client) usr.client.statobj = src
return ..()

verb/reincarnate() //return to the world of the living


obj
var
equiped
slot_name

verb
get()
drop()



obj/Food
text = "%"

var
//mob stat modifiers
life
aim
strength
armor
iq
immunity
karma

duration //number of additional digestion rounds
delay //pause (in ticks) between digestion rounds
//if duration==0, delay gives initial pause

parasite //parasite type (if any)
rot //shelf-life (in ticks)


proc
EatDesc()
DigestDesc()
Tick()

verb/eat()

obj/Food/Corpse/var
parasite_prob = 100 //probability of parasite


obj/Parasite
var
//food drain multipliers (fraction of food nutrients digested)
life
strength
aim
armor
iq
immunity

//run-time vars
tmp/mob/host

proc
Infect(host)
Digest(food)



obj/Weapon
var
aim //adds to user's aim
offense = 1 //multiplies user's offense

text = "("
slot_name = " (in hand)"

verb
wield()
remove()
throw()



obj/Armor
var
armor //adds to user's armor
defense = 1 //multiplies user's defense

text = "\["
slot_name = " (on body)"

verb
wear()
remove()



obj/Scroll
var/iq

text = "?"

proc
CastDesc() //no default so each scroll should define this
CastFail()

verb/read()



mob/verb
chicken()
usr.mood = CHICKEN

calm()
usr.mood = CALM
usr.Peace()

walk_mode()
usr.step_mode = WALK_STEP

join(mob/M as mob)
if(usr == M)
if(usr.rank >= 0)
usr.party_id = usr
usr.rank = 1
view() << "[usr] forms a new party."

else usr << "You are enslaved."

else
usr.party_id = M.party_id
usr.rank = 0
view() << "[usr] joins [M]'s party."


promote(mob/M as mob in oview())
if(usr.rank > M.rank)
M.rank = usr.rank
view() << "[usr] gives [M] a promotion."

else usr << "[usr] don't have the authority!"

follow(mob/M as mob|null)
if(!M)
M = usr.party_id
if(!ismob(M)) return

usr.step_trg = M
usr.step_mode = TRACK_STEP

control(mob/M as mob in usr.group)
if(!M.key) M.key = usr.key

push(mob/M as mob in oview(1))
view() << "[usr] pushes [M]."
M.Bump(usr)

kill(mob/M in oview())
usr.War(M)



mob/Read(savefile/F)
..()
//install parasites
var/plist = parasites
var/obj/Parasite/P
parasites = null
for(P in plist) P.Infect(src)

mob/New()
//init max stats
src.max_life = src.life
src.max_strength = src.strength
src.max_iq = src.iq
src.max_aim = src.aim
src.max_armor = src.armor
src.max_immunity = src.immunity

if(!src.party_id) src.party_id = src //self-aligned

src.Tick() //start up the mob ticker (which runs till the mob dies)
return ..()

mob/Stat()
var/S

if(statpanel(""))
if(src.desc) stat("description",src.desc)

if(src.max_life)
S = src.life/src.max_life
if(S < 0.25) stat("life","[src.max_life] very weak")
else if(S < 0.5) stat("life","[src.max_life] weak")
else if(S < 0.75) stat("life","[src.max_life] fair")
else stat("life","[src.max_life] strong")


if(src.max_strength)
S = src.strength/src.max_strength
if(S < 0.25) stat("strength","[src.max_strength] exhausted")
else if(S < 0.5) stat("strength","[src.max_strength] feeble")
else if(S < 0.75) stat("strength","[src.max_strength] fair")
else stat("strength","[src.max_strength] full")


if(src.max_iq)
S = src.iq/src.max_iq
if(S < 0.25) stat("mind","[src.max_iq] exhausted")
else if(S < 0.5) stat("mind","[src.max_iq] feeble")
else if(S < 0.75) stat("mind","[src.max_iq] fair")
else stat("mind","[src.max_iq] full")


if(src.max_aim)
S = src.aim/src.max_aim
if(S < 0.25) stat("armed","minimally")
else if(S < 0.5) stat("armed","lightly")
else if(S < 0.75) stat("armed","heavily")
else stat("armed","fully")


if(src.max_armor)
S = src.armor/src.max_armor
if(S < 0.25) stat("armored","minimally")
else if(S < 0.5) stat("armored","lightly")
else if(S < 0.75) stat("armored","heavily")
else stat("armored","fully")


if(!src.max_immunity) stat("immunity","none")
else
S = src.immunity/src.max_immunity
if(S < 0.25) stat("immunity","[src.max_immunity] very low")
else if(S < 0.5) stat("immunity","[src.max_immunity] low")
else if(S < 0.75) stat("immunity","[src.max_immunity] fair")
else stat("immunity","[src.max_immunity] strong")


stat("karma",round(src.karma))


if(src == usr && statpanel("inventory")) stat(src.contents)

mob/Bump(mob/Block)
if(ismob(Block))
//if friends, swap positions; otherwise this means war!
if(src.party_id == Block.party_id && src.rank >= Block.rank)
var/turf
loc1 = src.loc
loc2 = Block.loc
src.loc = 0
if(Block.Move(loc1)) src.loc = loc2
else src.loc = loc1

else src.War(Block)


mob/Del()
var/O
for(O in src.contents) del(O)
for(O in src.parasites) del(O)
return ..()

mob/Die()
var/mob/M
var/obj/O

if(src.corpse) new src.corpse(src.loc,src)

src.party_id = 0
for(M as mob in world)
if(M.party_id == src) src.ChangePartyLeader(src,M)

for(O in src) O.Move(src.loc) //drop everything

if(src.key)
//penalty for visiting the afterlife
//distribute karma between mob's energies (life, strength, iq)
var
kl = rand(1,10)
ks = rand(1,10)
ki = rand(1,10)
sum = kl + ks + ki

kl = -rand(src.karma * kl/sum)
ks = -rand(src.karma * ks/sum)
ki = -rand(src.karma * ki/sum)

src << "The karmic dice land with a great thump at your dead feet:\nlife: [kl]\nstrength: [ks]\niq: [ki]"

src.max_life += kl
src.max_strength += ks
src.max_iq += ki

if(src.max_life <=0) src.max_life = 1
if(src.max_strength <= 0) src.max_strength = 1
if(src.max_iq <= 0) src.max_iq = 1

src.GotoAfterlife()

else del(src) //creatures without souls don't have a second chance

mob/GotoAfterlife()
src.Move(locate(/area/Afterlife))

area/Afterlife/reincarnate()
//NOTE: this should probably be redefined by the world-specific code

var/Loc = locate(usr.corpse) //move to the corpse
if(usr.MoveNear(Loc)) return

var
x;y;z
dx = rand(world.maxx)
dy = rand(world.maxy)

//move to a random spot for lack of anything better to do
for(z=1,z<=world.maxz,z++)
for(x=0,x<world.maxx,x++)
for(y=0,y<world.maxy,y++)
var/turf/T = locate((x+dx)%world.maxx+1,(y+dy)%world.maxy+1,z)
if(usr.MoveNear(T)) return




mob/ChangePartyLeader(mob/gid,mob/DefaultLeader)
var/mob/M

//Promote highest ranking member to group leader (when previous one dies)
for(M as mob in world)
if(M.party_id == gid && M.rank > DefaultLeader.rank)
DefaultLeader = M

for(M as mob in world)
if(M.party_id == gid)
M.party_id = DefaultLeader
M << "Your new leader is [DefaultLeader]."




mob/MoveNoBump(Loc)
//move to Loc without bumping anything so nobody gets mad
var/D
var/ret

D = src.density
src.density = 0
ret = src.Move(Loc)
src.density = D
return ret

mob/MoveNear(turf/Center)
//move to a turf (or one of its neighbors) if there is a vacancy
var/turf/T
for(T as turf in view(1,Center))
if(T.Enter(src)) //check if it's possible to enter first
if(src.Move(T)) return 1




client
//stop any auto-movement modes when player takes over
North()
usr.step_mode = NO_STEP
return ..()

South()
usr.step_mode = NO_STEP
return ..()

East()
usr.step_mode = NO_STEP
return ..()

West()
usr.step_mode = NO_STEP
return ..()

Northeast()
usr.step_mode = NO_STEP
return ..()

Southeast()
usr.step_mode = NO_STEP
return ..()

Northwest()
usr.step_mode = NO_STEP
return ..()

Southwest()
usr.step_mode = NO_STEP
return ..()

Center()
usr.step_mode = NO_STEP
return ..()



mob
StepAway(trg,dist)
step_away(src,trg,dist)

StepTo(mob/trg,dist)
if(src.z <> trg.z) //follow down or up stairs
var/turf/T
var/zdiff = trg.z - src.z

for(T as turf in oview(src))
if(T.DeltaZOnUse() == zdiff)
if(get_dist(src,T) == 0) T.Use()
else step_to(src,T,0)
break



else step_to(src,trg,dist)

StepRand()
step_rand(src)

StepExplore()
var/D = src.dir
var/turf/T = get_step(src,D)

//move down a tunnel until there is a fork
if(T.DontExplore() || !src.Move(T))
T = get_step(src,turn(D,45))
if(T.DontExplore() || !src.Move(T))
T = get_step(src,turn(D,-45))
if(T.DontExplore() || !src.Move(T))
T = get_step(src,turn(D,-90))
if(T.DontExplore() || !src.Move(T))
T = get_step(src,turn(D,90))
if(T.DontExplore() || !src.Move(T))
src.step_mode = NO_STEP








mob/Tick()
//endless loop (automatically aborted when src dies)
spawn for()
sleep(src.step_lag)

if(src.enemy)
switch(src.mood)
if(CHICKEN) src.StepAway(src.enemy,5) //run away
if(WARY) src.StepAway(src.enemy,2) //stand clear
if(ASSERTIVE,HOSTILE) src.StepTo(src.enemy,1) //charge!


else
if(src.mood == HOSTILE) //look for some fresh meat
var/mob/O
for(O in oview(,src))
if(O.client)
src.War(O)
break



switch(src.step_mode)
if(RAND_STEP) src.StepRand()
if(TRACK_STEP)
if(!src.step_trg) src.step_mode = NO_STEP
else src.StepTo(src.step_trg,3)

if(WALK_STEP) src.StepExplore()





mob/War(mob/attacker)
//attacker has offended src

if(src.enemy==attacker) return //we already hate this guy
if(src.enemy) //we already hate somebody else
if(src.mood == ASSERTIVE) src.mood = HOSTILE //anger mounts!

//fight the new guy if he is closer
if(get_dist(src,src.enemy) < get_dist(src,attacker)) return

else spawn src.Swing() //start swinging

src.dir = get_dir(src,src.enemy)
src.enemy = attacker

var/mob/M
for(M as mob in oview(,src))
M.SeeWar(attacker,src)


mob/SeeWar(attacker,mob/trg)
//attacker has offended trg--do we care?
if(src.party_id && src.party_id == trg.party_id && src.rank <= trg.rank)
src.War(attacker) //yes we care because trg is a friend


mob/Peace()
src.enemy = 0

mob/OneSwing(mob/trg,Aim,Offense)
var/p
var/x

src.dir = get_dir(src,trg) //face the enemy

//sigmoidal hit probability
if(trg.armor + Aim == 0) return
x = (trg.armor - Aim)/(trg.armor + Aim)
p = 1/(1 + 100 ** x)

trg.War(src)
if(prob(p*100))
//improve aim skill
src.max_aim += 0.1 * (1-p)

p *= -0.07 * src.strength //hit energy
src.AddStrength(p)
p *= Offense/trg.defense

switch(-p/trg.max_life)
if(0.00 to 0.10) view() << "[src] grazes [trg]."
if(0.10 to 0.25) view() << "[src] hits [trg]."
if(0.25 to 0.50) view() << "[src] smashes [trg]."
else view() << "[src] sends [trg] reeling."


trg.AddLife(p)
return p

else
//improve armor skill
trg.max_armor += 0.1 * p


mob/Swing()
spawn
usr = src //so procs like AddLife give credit where it is due

while(src.enemy)
if(get_dist(src,src.enemy) <= 1) //in range
src.OneSwing(src.enemy,src.aim,src.offense)


//next swing is randomly delayed anywhere up to swing_lag
sleep(rand(src.swing_lag))

src.Peace()



mob/AddLife(N)
//returns actual amount added to life
var/V

V = src.life + N
if(V > src.max_life)
src.AddKarma(V-src.max_life) //gluttony!

V = src.max_life
N = V - src.life
src.life = V

else if(V < 0)
if(usr && usr!=src) view(,src) << "[usr] kills [src]!"
src.Die()

else src.life = V

//increase max_life with probability N/max_life
if(N>0 && N > rand(src.max_life))
src << "You feel lively."
src.max_life++

return N

mob/AddStrength(N)
//returns actual amount added to strength
var/V

V = src.strength + N
if(V > src.max_strength)
src.AddKarma(V-src.max_strength) //gluttony!

V = src.max_strength
N = V - src.strength

else if(V < 0)
V = 0
N = V - src.strength

src.strength = V

//increase max_strength with probability N/max_strength
if(N>0 && N > rand(src.max_strength))
src << "You feel stronger!"
src.max_strength++

return N

mob/AddIQ(N)
//returns actual amount added to iq
var/V

V = src.iq + N
if(V > src.max_iq)
src.AddKarma(V-src.max_iq) //gluttony!

V = src.max_iq
N = V - src.iq

else if(V < 0)
V = 0
N = V - src.iq

src.iq = V

//increase max_iq with probability N/max_iq
if(N>0 && N > rand(src.max_iq))
src << "You feel rather clever."
src.max_iq++

return N

mob/AddAim(N)
//returns actual amount added to aim
var/V

V = src.aim + N
if(V > src.max_aim)
V = src.max_aim
N = V - src.aim

else if(V < 0)
V = 0
N = V - src.aim

src.aim = V

return N

mob/AddArmor(N)
//returns actual amount added to armor
var/V

V = src.armor + N
if(V > src.max_armor)
V = src.max_armor
N = V - src.armor

else if(V < 0)
V = 0
N = V - src.armor

src.armor = V

return N

mob/AddImmunity(N)
//returns actual amount added to immunity
var/V

V = src.immunity + N
if(V > src.max_immunity)
V = src.max_immunity
N = V - src.immunity

else if(V < 0)
V = 0
N = V - src.immunity

src.immunity = V

if(N>0 && N > rand(src.max_immunity))
src << "You feel healthier."
src.max_immunity++

return N

mob/AddKarma(N)
src.karma += N
if(src.karma < 0)
N -= src.karma
src.karma = 0

return N

mob/AddParasite(obj/Parasite/p)
if(!src.parasites) src.parasites = list(p)
else src.parasites.Add(p)

mob/RemoveParasite(obj/Parasite/p)
if(src.parasites)
src.parasites.Remove(p)
if(!src.parasites.len) src << "The gnawing in your guts ceases abruptly."


mob/SetName(NewName)
var/mob/M
if(!NewName) return
//don't allow changing to sombody else's key name
if(NewName!=src.key)
for(M in world) if(M.key == NewName) return

src.name = NewName
return 1

client/New()
var/ret = ..()

//nobody may impersonate a key
var/mob/M
for(M as mob in world)
if(M == src.mob) continue
if(M.name == src.key)
if(M.key) M.SetName(M.key)


return ret


turf/DontExplore()
var/M
//don't explore if turf contains mobs
for(M as mob in src) return 1;


obj/get()
set src in oview(0)
if(src.Move(usr))
view() << "[usr] picks up \a [src]."


obj/drop()
set src in usr
if(src.Move(usr.loc))
view() << "[usr] drops \a [src]."


obj/Food/New()
src.Tick()
return ..()

obj/Food/EatDesc()
view() << pick(
"[usr] eats \a [src].",
"[usr] devours \a [src].")

obj/Food/DigestDesc()
if(src.life>=0 && src.aim>=0 && src.armor>=0 && src.strength>=0 && src.iq>=0)
if(prob(10)) view() << "[usr] belches contentedly."


obj/Food/Tick()
var/S
spawn while(src.rot)
S = src.rot
sleep(S)
src.rot -= S
if(src.rot == 0)
del(src)
return

else if(src.rot < 0) break


obj/Food/eat()
var/count
count = src.duration

src.loc = 0 //dissappear
src.EatDesc()

var/obj/Parasite/p
for(p in usr.parasites) p.Digest(src)

if(!count && src.delay) sleep(src.delay)
do
usr.AddLife(src.life)
usr.AddAim(src.aim)
usr.AddStrength(src.strength)
usr.AddArmor(src.armor)
usr.AddIQ(src.iq)
usr.AddImmunity(src.immunity)
usr.AddKarma(src.karma)

src.DigestDesc()
if(count) sleep(src.delay)
while(count--)
if(src.parasite) new src.parasite(usr)
del(src)

obj/Food/Corpse/New(Loc,mob/LiveSrc)
src.name = addtext(src.name," corpse")
if(!prob(src.parasite_prob)) src.parasite = 0
if(LiveSrc.parasites && LiveSrc.parasites.len)
var/obj/Parasite/p
p = LiveSrc.parasites[rand(1,LiveSrc.parasites.len)]
src.parasite = p.type

src.karma = LiveSrc.karma
return ..()

obj/Parasite/New(mob/Host)
//when loading from file Host==0
if(Host)
src.immunity += Host.AddImmunity(-src.immunity)
if(!src.immunity)
if(prob(30)) usr << "Your stomach juices go to work."
del(src)
return

src.Infect(Host)

return ..(null)

obj/Parasite/Del()
if(src.host) src.host.RemoveParasite(src)

obj/Parasite/Infect(mob/Host)
src.host = Host
src.host.AddParasite(src)

obj/Parasite/Digest(obj/Food/f)
f.life *= (1-src.life)
f.strength *= (1-src.strength)
f.aim *= (1-src.aim)
f.armor *= (1-src.armor)
f.iq *= (1-src.iq)

if(f.immunity >= src.immunity)
f.immunity -= src.immunity
src.immunity = 0
del(src)

else src.immunity -= f.immunity


obj/Weapon/wield()
if(!src.equiped)
var/obj/O
for(O in usr)
if(O.equiped && O.slot_name == src.slot_name)
usr << "You are already using [O]."
return 0


src.suffix = src.slot_name
src.equiped = 1
view() << "[usr] wields \a [src]."

usr.AddAim(src.aim)
usr.offense *= src.offense
return 1


obj/Weapon/remove()
if(src.equiped)
src.suffix = ""
src.equiped = 0
view() << "[usr] removes \his [src.name]."

usr.AddAim(-src.aim)
usr.offense /= src.offense
return 1


obj/Weapon/throw(mob/Trg as mob)
src.suffix = ""
src.equiped = 0

//TODO: swing only once missile has struck
//TODO: subtract out the current weapon's stats from swing
missile(src,usr,Trg.loc)
src.Move(Trg.loc)
usr.OneSwing(Trg,src.aim+usr.aim,src.offense+usr.offense)

obj/Armor/wear()
if(!src.equiped)
var/obj/O
for(O in usr)
if(O.equiped && O.slot_name == src.slot_name)
usr << "You are already wearing [O]."
return 0


src.suffix = src.slot_name
src.equiped = 1
view() << "[usr] wears \a [src]."

usr.AddArmor(src.armor)
usr.defense *= src.defense


obj/Armor/remove()
if(src.equiped)
src.suffix = ""
src.equiped = 0
view() << "[usr] removes \his [src.name]."

usr.AddArmor(-src.armor)
usr.defense /= src.defense



obj/Scroll/read()
set src in usr

//sigmoidal success probability
var/x = (src.iq - usr.iq)/(src.iq + usr.iq)
var/p = 100/(1 + 100 ** x)

usr.AddIQ(-src.iq)
if(prob(p))
var/cdesc = src.CastDesc()
if(cdesc) view() << cdesc
return 1

else src.CastFail()

obj/Scroll/CastFail()
usr << pick(
"You feel a bit light headed.",
"Mmm. You smell sizzled neurons.",
"The words swim before your eyes.")

In response to Gilser
mob/player
human
icon = 'player.dmi'
Login()
loc = locate(10, 10, 1)

client/proc/RefreshEye()
var/target = src.mob
if(!target)
return

var/x = target:x
var/y = target:y
if(x < world.view+1)
x = world.view+1
if(y < world.view+1)
y = world.view+1
if(x > world.maxx-world.view)
x = world.maxx-world.view
if(y > world.maxy-world.view)
y = world.maxy-world.view

//world << "X: [x], Y: [y]" //debug line

var/turf/T = locate(x,y,src.mob.z)
if(T == src.mob.loc)
src.eye = src.mob
else
src.eye = T


mob/badguy
icon = 'bigblob.dmi'
blob
life = 2
strength = 2
aim = 3
armor = 2
offense = 1.5
karma = 2
/*Login/Logout*/

mob
Login()
world << "[usr] enters the world."

Logout()
world << "[usr] leaves the world."

/*People can chat */

mob/verb/say (msg as text)


world << "[usr]: [msg]"
In response to Gilser
it'll be called OS
In response to Gilser
It looks to me like your player mob is enheriting the instructions you have for the enemy mobs.
You will have to place the instructions for your A.I. intop thier own catagory like this
mob
player
player stats
creature
A.I.

If your a little foggy on what I mean, read on.
The way everything is handled in DM is to be though of like a family tree.
Whatever your parents are, you will enherit their instructions or DNA.(I know some dissagree but this is just for explanation purposes. ;-) )
So if you have something like this..
mob
icon='default.dmi'
Dragon
icon = 'drag.dmi'

GreatDragon

Golem
icon = 'golm.dmi'
KillerBunny
icon = 'kbun.dmi'

player
human
icon = 'human.dmi'
elf

gnome
icon = 'gnome.dmi'

Okay notice how under mob i have icon ='default'.
Now every single thing under mob will have the icon assigned to it called default unless you specify otherwise because they enherit it from being under it. Now when I saw under I don't neccesarily mean directly under, I mean the fact that they are endented under mob.
Notic how they all have thier own icons assigned to them exept for 'elf'. Elf will have the icon of default.dmi because nothing else was given to it and it's enheriting what was given to its parent which is Mob.
If you want elf to have its own icon you gotta assign one under it.
Notice how GreatDragon has no icon assigned to it? Well its parent is Dragon so it's icon will be the same as it's parent which is dragon. if you didn't give dragon it;s own icon it would get the icon default.dmi and GreatDragon would inherit that icon too from it's parent.

Phew, I hope that helps. So now you may now what I mean if you didnt before about that your player mob may be enheriting the mob's Artificial Intelegence to attack on it's own.