P_SpawnMobjFromMobj not working

Dodobee

Avid Among us enjoyer
I really don't understand what's going on but it just doesn't spawn anything at all
Lua:
addHook("MobjThinker", function(mo) -- runs once per player each frame
    if mo.extraenemyx == nil then
        mo.extraenemyx = P_RandomRange(-3, 3)
    end
    
    if mo.extraenemyy == nil then
        mo.extraenemyy = P_RandomRange(-3, 3)
    end
    
    if mo.doitonce == false then
    P_SpawnMobjFromMobj(mo, mo.extraenemyx*3*FRACUNIT, mo.extraenemy*3*FRACUNIT, 0, mo.type)
    end
    
    if mo.doitonce == nil then
        mo.doitonce = false
    end
    
    if mo.doitonce == false then
    mo.scale = $/2
    mo.doitonce = true
    end
end)
 
I really don't understand what's going on but it just doesn't spawn anything at all
Lua:
addHook("MobjThinker", function(mo) -- runs once per player each frame
    if mo.extraenemyx == nil then
        mo.extraenemyx = P_RandomRange(-3, 3)
    end
  
    if mo.extraenemyy == nil then
        mo.extraenemyy = P_RandomRange(-3, 3)
    end
  
    if mo.doitonce == false then
    P_SpawnMobjFromMobj(mo, mo.extraenemyx*3*FRACUNIT, mo.extraenemy*3*FRACUNIT, 0, mo.type)
    end
  
    if mo.doitonce == nil then
        mo.doitonce = false
    end
  
    if mo.doitonce == false then
    mo.scale = $/2
    mo.doitonce = true
    end
end)
Took me some time to realize this, but it seems like mo.doitonce was nil during that moment, probably causing a Lua error because your code assumed it had a value.
Try putting your P_SpawnMobjFromMobj function together with the scale thingy at the end.

EDIT: You're using mo.extraenemy instead of mo.extraenemyy in the P_SpawnMobjFromMobj function. Make sure to fix that!
 
Last edited:
Thanks, it works but I just realized that because mo creates doitonce for every object when it spawns, the game kept spawning extra copies of enemies and crashed
Post automatically merged:

Sorry to disturb but I really have no idea how to make the game stop spawning objects. I tried using a player. variable to make it work but it made everything normal sized and didn't spawn anything
Post automatically merged:

(I'm really sorry for my constant yapping) I made some adjustments to the code but its still not working as intended. It keeps spawning enemies so the game crashes
Lua:
addHook("MobjThinker", function(mo)
    if mo.doitonce == nil then
        mo.doitonce = false
    end
    
    if mo.extraenemyx == nil then
        mo.extraenemyx = P_RandomRange(-3, 3)
    end
    
    if mo.extraenemyy == nil then
        mo.extraenemyy = P_RandomRange(-3, 3)
    end
    
    if (mo.flags & MF_ENEMY)
    and not mo.extraenemy then
    mo.extraenemy = P_SpawnMobjFromMobj(mo, mo.extraenemyx*3*FRACUNIT, mo.extraenemyy*3*FRACUNIT, 0, mo.type)
    end
    
    if mo.doitonce == false then
    mo.scale = $/2
    mo.doitonce = true
    end
end)
 
Last edited:
I'm assuming the enemies you spawn create their own copies, since "doitonce" doesn't actually do anything.

if mo.doitonce == true return end after line 4, and mo.extraenemy.doitonce = true after line 16 should most likely work. There are more elegant ways to handle it but whatever.
 
They spawn now but one of the enemies stays at normal size while the other is scaled properly, and I believe I did P_RandomRange incorrectly because both enemies spawn inside each other

EDIT: I fixed the problem with the copy having an unchanged size but they're all facing in one direction(I assume thats normal but is there a way to make them face towards the player) and for the second problem, turns out P_RandomRange was working completely fine, I just barely multiplied it so that the spawned enemies are far enough :P
 
Last edited:
EDIT: I fixed the problem with the copy having an unchanged size but they're all facing in one direction (I assume thats normal but is there a way to make them face towards the player) :P
You can use R_PointToAngle2(x, y, targetx, targety) to make the copy's angle face the player.

In cases like this, you want x and y to be your object's X and Y positions respectively, while targetx and targety should be the X and Y positions your object should look at.

Here's a little example of what you can do with R_PointToAngle2. This 4-line script forces the player to look directly to the camera:
R_PointToAngle2 example script:
addHook("PlayerThink", function(player) -- Functions hooked to "PlayerThink" run every tic for players
    if not (player.mo and player.mo.valid) return end -- Stop the function if we don't exist
    player.drawangle = R_PointToAngle2(player.mo.x, player.mo.y, camera.x, camera.y) -- Change our drawangle to face our camera
end) -- The function ends here
 
Tried this and for some reason its still not working. All the copies are facing forward still and don't move unless the player goes in front of them

Lua:
addHook("MobjThinker", function(mo)
    if not (mo.extraenemy and mo.extraenemy.valid) return end
    mo.extraenemy.drawangle = R_PointToAngle2(mo.extraenemy.x, mo.extraenemy.y, player.mo.x, player.mo.y)
end)
 
Tried this and for some reason its still not working. All the copies are facing forward still and don't move unless the player goes in front of them

Lua:
addHook("MobjThinker", function(mo)
    if not (mo.extraenemy and mo.extraenemy.valid) return end
    mo.extraenemy.drawangle = R_PointToAngle2(mo.extraenemy.x, mo.extraenemy.y, player.mo.x, player.mo.y)
end)
Yeah... Huh... The drawangle variable is only for players. In cases of objects without an assigned player, use angle instead.

And instead of player.mo, use mo.target. By the way, check if mo.target exists, just like with mo.extraenemy.
 
For some reason it just randomly stopped working. I haven't made any adjustments to the code for the enemy pointing and the rest of the code works just fine.
Lua:
    if mo.extraenemyvar == nil then
        mo.extraenemyvar = false
    end

    if not (mo.extraenemy and mo.extraenemy.valid)
    or not (mo.target and mo.target.valid)
    or mo.extraenemyvar == true return end
    mo.extraenemy.angle = R_PointToAngle2(mo.extraenemy.x, mo.extraenemy.y, mo.target.x, mo.target.y)
    mo.extraenemyvar = true
 
For some reason it just randomly stopped working. I haven't made any adjustments to the code for the enemy pointing and the rest of the code works just fine.
Lua:
    if mo.extraenemyvar == nil then
        mo.extraenemyvar = false
    end

    if not (mo.extraenemy and mo.extraenemy.valid)
    or not (mo.target and mo.target.valid)
    or mo.extraenemyvar == true return end
    mo.extraenemy.angle = R_PointToAngle2(mo.extraenemy.x, mo.extraenemy.y, mo.target.x, mo.target.y)
    mo.extraenemyvar = true
This piece of code doesn't seems to have any problems...

Do you recieve any WARNING messages on your game's console when running your addon? If you do, tell me what they do say.
You might also want to show me all the code, as the previously mentioned messages will refer to specific lines of your script.
 
There's a warning saying MobjThinker hooks are deprecated and will be removed but it said that before and it still worked. Here's the rest of the code:
Lua:
addHook("MobjThinker", function(mo)
    if mo.doitonce == nil then
        mo.doitonce = false
    end
    if mo.doitonce == true return
    end
   
    if mo.extraenemyx == nil then
        mo.extraenemyx = P_RandomRange(-5, 5)
    end
   
    if mo.extraenemyy == nil then
        mo.extraenemyy = P_RandomRange(-5, 5)
    end
   
    if mo.doitonce == false then
    mo.scale = $/2
    mo.doitonce = true
    end
   
    if (mo.flags & MF_ENEMY)
    and not mo.extraenemy then
    mo.extraenemy = P_SpawnMobjFromMobj(mo, mo.extraenemyx*35*FRACUNIT, mo.extraenemyy*35*FRACUNIT, 0, mo.type)
    mo.extraenemy.doitonce = true
    end
   
    if mo.extraenemyvar == nil then
        mo.extraenemyvar = false
    end
   
    if not (mo.extraenemy and mo.extraenemy.valid)
    or not (mo.target and mo.target.valid)
    or mo.extraenemyvar == true return end
    mo.extraenemy.angle = R_PointToAngle2(mo.extraenemy.x, mo.extraenemy.y, mo.target.x, mo.target.y)
    mo.extraenemyvar = true
end)
 
That's because MobjThinker hooks that don't have an object type target (like MT_BLUECRAWLA) apply to EVERY mobj that doesn't have MF_NOTHINK. Which means massive lag, so it's on the chopping block for 2.3 (I think).

Ideally you'd put this on the MobjSpawn hook, but you can't, because MobjSpawn runs IMMEDIATELY after P_SpawnMobj, so you wouldn't get the chance to set doitonce to true before the game blows up.

Either you create a table with all the object types (MT_BLUECRAWLA aaalll the way to MT_CYBRAKDEMON), and use a for-loop on that table to add this hook to those enemies only, but that wouldn't support custom enemies. Or you can try to add this to MapThingSpawn so that only enemies put inside the map itself create copies.
 
So is there any problems with the code?
Aside from what Zipper pointed out, I don't see any other problems. I might try to run the code later and play around with it to see what's wrong.
 

Who is viewing this thread (Total: 1, Members: 0, Guests: 1)

Back
Top