ID:1932968
 
(See the best response by Ter13.)
Problem description: This is not the first time I posted something about projectiles. I just can't seem to get them working. What I am looking for is some sort of system that will handle any type of interaction between projectiles objects and the mob, and as well as other objects for the just in case. I want to be able to detect with "crossed" proc in cases where:

-Projectile crosses mob/obj
-mob/obj crosses projectile
-Projectile is placed on the mobs location.

This is my current attempt:

obj/projectile

layer = 5
density = 1
var/tmp

speed = 1
critical = null
duration = 50
breakable = TRUE
mob/owner = null
mob/target = null
stand_still = null
attack_type = null
damage_amount = null
guard_ignorant = FALSE
movement_limit = FALSE



New(loc, dir, mob/owner, mob/target)

src.dir = dir
src.loc = loc
src.owner = owner
src.target = target
src.projectile_fire(target)

if(istype(src, /obj/projectile/mage/unleash))
for(var/mob/m in oview(src, 2))
var/teamate = owner._check_teamate(m)
if(teamate) return

var damage = owner.get_damage(defender = m, damage_amount = src.damage_amount)

m.core_loss(m.health, amt = damage)
owner.show_damage(m, "<b>[damage]","#fff")

//Unleash applies a burn for 3 seconds.
var/ability/a = locate(/ability/mage/active/unleash) in owner.ability_list
if(a && a.rank > 3) owner.apply_condition(defender = m, condition = "burn", duration = 30)

..()


/*onCrossed(atom/movable/a)
//You don't need to check if special is unlocked, because you already did it when you excuted the ability
world << "[a]"
if(isturf(a) && isobj(a)) del src

else if(ismob(a))
if(a == owner) return

else
var/mob/defender = a
var/teamate = src.owner._check_teamate(a)
//if(teamate) return

var/damage = src.owner.get_damage(defender = defender, attack_type = src.attack_type, guard_ignorant = src.guard_ignorant, \
critical = src.critical, damage_amount = src.damage_amount)

if(isnum(damage))

defender.core_loss(defender.health, amt = damage)

owner.show_damage(defender, "<b>[damage]","#fff")
if(src.breakable) del(src)*/


proc

projectile_fire(var/target_lock = FALSE)
if(!stand_still)
//code homing system here
if(target_lock && owner.target)

walk_towards(src,owner.target,world.tick_lag * src.speed)


else
walk(src, src.dir, src.speed)

//else
// new/obj/effect(icon = '_ground_effects.dmi',icon_state = "tiney_crater", loc = src.loc)

duration += round(duration * (owner.apply_vital_boost(owner.duration) / 100))

if(src) spawn(duration) del(src)
Best response
onCrossed() doesn't do anything because you need my MoveLib to make it work, and my MoveLib is private. I've only sold it to three people, and I find it really interesting that you are trying to use onCrossed(), which is a function that I solely use.

Though, I suppose you could take a look at a prototype version of it I shared here:

http://www.byond.com/forum/?post=1901373#comment16036887

Blatant plug, I sell copies of a fully-featured pixel projectile library for $150 a license if you want the milk straight from the source.
Thanks for responding. Actually that's exactly where I got it from. I still can't detect when projectiles come in contact with the mob. Having said, there are some occasions where I can detect the interaction but I still need it to meet the criterias I mentioned. $150 is too hefty for an unemployed individual like myself.
Crossed() is called when something overlaps THIS object.

There is no built-in function for when THIS object overlaps something.

That's why I defined onCrossed(). It gives you full access to objects overlapping. Provided you use the source in the link I provided, onCrossed() and Crossed() both should be used in conjunction on the same object to provide the behavior you need.
Alright I think I almost got it. The Crossed() works perfectly. At the time being however, I am having trouble with onCrossed(). Like before, I can't seem to detect when the object overlaps another. I am most likely overlooking something and I am not sure what that could be. Thank you.

obj/projectile/mage
unleash
icon = '_mage_unleash.dmi'
attack_type = "spiritual"
stand_still = TRUE
pixel_x = -54
pixel_y = -64
duration = 9

Crossed(mob/m) if(istype(m)) unleash(m)

onCrossed(mob/m) if(istype(m)) unleash(m)

proc/unleash(mob/m)
for(m in oview(src, 2))
var/teamate = owner._check_teamate(m)
if(teamate) return

var damage = owner.get_damage(defender = m, damage_amount = src.damage_amount)

m.core_loss(m.health, amt = damage)
owner.show_damage(m, "<b>[damage]","#fff")

//Unleash applies a burn for 3 seconds.
var/ability/a = locate(/ability/mage/active/unleash) in owner.ability_list
if(a && a.rank > 3) owner.apply_condition(defender = m, condition = "burn", duration = 30)
Any ideas?
Have you tried just using onCrossed without the Crossed? Comment out the Crossed and see what happens. That is my thoughts/what I would try. Check all avenues!
In response to AERProductions
I have but the problem still persists. It is failing to detect the mob.
Crossed(mob/m) if(istype(m)) unleash(m)
onCrossed(mob/m) if(istype(m)) unleash(m)
istype(m,/mob)
In response to Kozuma3
Not necessary.
Here is some other code that maybe be useful

obj/projectile

layer = 5

var/tmp

speed = 1
critical = null
duration = null
breakable = TRUE
mob/owner = null
mob/target = null
stand_still = null
attack_type = null
damage_amount = null
guard_ignorant = FALSE
movement_limit = FALSE


proc
set_and_fire(loc, dir, mob/owner, mob/target)
src.dir = dir
src.loc = loc
src.owner = owner
src.target = target
if(!stand_still) src.projectile_fire(target)
else projectile_summon()


projectile_fire(var/target_lock = FALSE)

if(target_lock && owner.target) walk_towards(src,owner.target,src.speed)

else walk(src, src.dir, src.speed)

duration += round(duration * (owner.apply_vital_boost(owner.duration) / 100))

if(src) spawn(50 + duration) del(src)


projectile_summon()

if(src) spawn(duration) del(src)


And also Ter13's snippet:

//Just some quick analogues. Basically, these allow better projectile and collision programming a lot easier.
//onEnter() is called on a movable atom when it tries to enter a turf. This lets the mover have the final say
//in what happens during a movement, not just the turf.
//on-variants are called on the opposite object of where their non-on variants are called.
atom
proc
Bumped(atom/movable/O)

//Enter(atom/movable/O,atom/oldloc)
// . = O.onEnter(src,oldloc)

Exit(atom/movable/O,atom/newloc)
. = O.onExit(src,newloc)

Entered(atom/movable/O,atom/oldloc)
O.onEntered(src,oldloc)

Exited(atom/movable/O,atom/newloc)
O.onExited(src,newloc)

movable
proc
onEnter(atom/O,atom/oldloc)
. = !(density&&O.density)

onExit(atom/O,atom/newloc)
. = 1

onCross(atom/movable/O)
. = !(density&&O.density)

onUncross(atom/movable/O)
. = 1

onEntered(atom/movable/O,atom/oldloc)
onExited(atom/movable/O,atom/newloc)
onCrossed(atom/movable/O)
onUncrossed(atom/movable/O)

Cross(atom/movable/O)
. = O.onCross(src)

Uncross(atom/movable/O)
. = O.onUncross(src)

Crossed(atom/movable/O)
O.onCrossed(src)

Uncrossed(atom/movable/O)
O.onUncrossed(src)

Bump(atom/O)
O.Bumped(src)
The only reason that onCrossed() would not be getting called is if you have overidden mob/Crossed() and failed to trigger the default behavior.
In response to Ter13
I have searched through the whole project and the above post is the only time where mob/Crossed() is declared. I am failing to understand.
In response to Luchasi
Luchasi wrote:
I have searched through the whole project and the above post is the only time where mob/Crossed() is declared. I am failing to understand.

Sounds to me like ter pointed out the exact problem, then. Somewhere in that code you have overwritten the declaration you see. At least, this is my thoughts on this.

I wish I were a capable programmer because I could easily fix it for you, but you wouldn't learn anything that way! None of us would! :)

Have you tried randomly fixing/messing with it and adding debugging messages, etc?
Could add some test msg when the objects pass over (or don't) and this can help you locate where the code isn't functioning or where it is overlapping.
I have searched through the whole project and the above post is the only time where mob/Crossed() is declared. I am failing to understand.

In the above code, mob/Crossed() isn't declared, though.
In response to Ter13
Ter13 wrote:
I have searched through the whole project and the above post is the only time where mob/Crossed() is declared. I am failing to understand.

In the above code, mob/Crossed() isn't declared, though.

Well he seems to think that it is declared in that spot, so this must be the culprit!
In response to Kozuma3
Kozuma3 wrote:
Crossed(mob/m) if(istype(m)) unleash(m)
> onCrossed(mob/m) if(istype(m)) unleash(m)
istype(m,/mob)

There's a little known syntax quirk in istype() where if the second argument isn't provided, it'll check against the cast type of the variable.

So istype(m) will look at the type that the variable is declared as (in this case /mob), and supply it automatically as the second argument.

I don't know if there's a speed benefit, but I prefer the pattern.
In response to Ter13
Ter13 wrote:
Kozuma3 wrote:
Crossed(mob/m) if(istype(m)) unleash(m)
> > onCrossed(mob/m) if(istype(m)) unleash(m)
istype(m,/mob)
There's a little known syntax quirk in istype() where if the second argument isn't provided, it'll check against the cast type of the variable.

So istype(m) will look at the type that the variable is declared as (in this case /mob), and supply it automatically as the second argument.

I don't know if there's a speed benefit, but I prefer the pattern.

So would adding the second argument help, something like:
if(istype(usr,/mob/m))
In response to Ter13
Ter13 wrote:
Kozuma3 wrote:
Crossed(mob/m) if(istype(m)) unleash(m)
> > onCrossed(mob/m) if(istype(m)) unleash(m)
istype(m,/mob)
There's a little known syntax quirk in istype() where if the second argument isn't provided, it'll check against the cast type of the variable.

Ah that's pretty interesting.
I don't think you understood what I just said, AER.

The second argument for istype is optional.

istype(usr)


Will always check if usr is of type /mob. Usr is always of type /mob, though, so it's worthless to apply that pattern to usr.

When checking the usr's type, though, there's two patterns you can use to do so:

if(istype(usr,/mob/player))
var/mob/player/p = usr
p.doSomething()


Or:

var/mob/player/p = usr
if(istype(p))
p.doSomething()


The pattern breaks down, though with more than one type check. I tend to avoid this issue entirely by ensuring that my behavior is encapsulated properly in the first place in helper objects.
Page: 1 2