ID:2310614
 
(See the best response by Ter13.)
Code:
var
list/coinlist = new

proc/globalLoop()
while(1)
for(var/obj/coin/coin in coinlist)
coin.gotoTarget()
sleep(world.tick_lag)

obj
coin
icon = 'Money.dmi'
density = 0
var value
var mob/combat/player/target
var/rank
var/stepcount
bronze
icon_state = "bronze"
rank=1
silver
icon_state = "silver"
rank=2
gold
icon_state = "gold"
rank=3
diamond
icon_state = "diamond"
rank=4
glide_size = 2

proc/gotoTarget()
if(!target) del src
// if(ActionLock("coinlock", world.tick_lag)) return
step_towards(src,target)
stepcount++
if(stepcount>35)
target.addCoin(rank,value)
del src
// if(target.x == src.x && target.y == src.y && target.z == src.z)
if(target.loc == src.loc)
target.addCoin(rank,value)
del src


proc/generateCoins(rank,count,mobloc,atom/target)
var coins = round(count / 333)
var rmnd = count % 333
var/obj/coin/setcoin = new
switch(rank)
if(1)
setcoin = new /obj/coin/bronze
if(2)
setcoin = new /obj/coin/silver
if(3)
setcoin = new /obj/coin/gold
if(4)
setcoin = new /obj/coin/diamond

for(var/i=coins,i>0,i--)
// new setcoin
setcoin.value = 333
setcoin.pixel_x += rand(0,5)
setcoin.pixel_y += rand(0,5)
setcoin.loc = mobloc
setcoin.target = target
coinlist += new setcoin

if(rmnd > 0)
setcoin.value = rmnd
setcoin.pixel_x += rand(0,5)
setcoin.pixel_y += rand(0,5)
setcoin.loc = mobloc
setcoin.target = target
coinlist += new setcoin


Problem description:

The desired result is to have multiple coins spawn on the ground and instead only 1 coin spawns on each type. they also don't move or get added to coinlist. I also receive this error:



runtime error: Cannot create objects of type /obj/coin/bronze.
proc name: generateCoins (/proc/generateCoins)
usr: Guest-156831082 (/mob/combat/player)
src: null
usr.loc: LightDirt13 (23,22,1) (/turf/Environment/Ground/Dirt/LightDirt/LightDirt13)
call stack:
generateCoins(1, 3, LightDirt06 (23,23,1) (/turf/Environment/Ground/Dirt/LightDirt/LightDirt06), Guest-156831082 (/mob/combat/player))
the slimeblue (/mob/combat/enemy/slimeblue): React()
/value (/value): Subtract(2)
damageEnemy(Guest-156831082 (/mob/combat/player), the slimeblue (/mob/combat/enemy/slimeblue))
Guest-156831082 (/mob/combat/player): Bump(the slimeblue (/mob/combat/enemy/slimeblue))
Guest-156831082 (/mob/combat/player): Move(LightDirt06 (23,23,1) (/turf/Environment/Ground/Dirt/LightDirt/LightDirt06), 1)
Guest-156831082 (/client): default action("north")
Guest-156831082 (/client): key down("north", Guest-156831082 (/client))
Guest-156831082 (/client): KeyDown("north")
runtime error: Cannot create objects of type /obj/coin/silver.
proc name: generateCoins (/proc/generateCoins)
usr: Guest-156831082 (/mob/combat/player)
src: null
usr.loc: LightDirt13 (23,22,1) (/turf/Environment/Ground/Dirt/LightDirt/LightDirt13)
call stack:
generateCoins(2, 1, LightDirt06 (23,23,1) (/turf/Environment/Ground/Dirt/LightDirt/LightDirt06), Guest-156831082 (/mob/combat/player))
the slimeblue (/mob/combat/enemy/slimeblue): React()
/value (/value): Subtract(2)
damageEnemy(Guest-156831082 (/mob/combat/player), the slimeblue (/mob/combat/enemy/slimeblue))
Guest-156831082 (/mob/combat/player): Bump(the slimeblue (/mob/combat/enemy/slimeblue))
Guest-156831082 (/mob/combat/player): Move(LightDirt06 (23,23,1) (/turf/Environment/Ground/Dirt/LightDirt/LightDirt06), 1)
Guest-156831082 (/client): default action("north")
Guest-156831082 (/client): key down("north", Guest-156831082 (/client))
Guest-156831082 (/client): KeyDown("north")
You are passing an object instance where you should be passing an object type (or path).
Best response
proc/generateCoins(rank,count,mobloc,atom/target)
var/cointype, obj/coin/coin, value
switch(rank)
if(1)
cointype = /obj/coin/bronze
if(2)
cointype = /obj/coin/silver
if(3)
cointype = /obj/coin/gold
if(4)
cointype = /obj/coin/diamond

while(count>0)
coin = new cointype
coin.value = (value = min(count,333))
coin.pixel_x += rand(-5,5)
coin.pixel_y += rand(-5,5)
coin.loc = mobloc
coin.target = target
coinlist += coin
count -= value


A few changes I made:

1) Got rid of new keyword everywhere it wasn't needed.

2) Created a variable to store the type for the duration of the function, and a variable to store the coin created for the duration of the loop.

3) Got rid of the iterative for condition loop in favor of a while condition loop. This gets rid of the need to calculate the number of coins and the remaining value.

4) Combined the logic for the creation of the remainder and full value coins to eliminate duplicate code.

5) changed the names of the variables to be less confusing for you. (You were getting a bit confused).


Did a second pass fix over the top bit as well: There was quite a bit going on here that was a problem.

Your coinlist was unsafe because manual deletion was leaving blank spots in it. This was basically a progressive leak that would make the global loop slow down over time. The thing is that your gotoTarget() proc was able to be better optimized to more quickly remove the coins given situations where the player isn't able to be pathed to.

The other major issue I fixed now affects the above code. It keeps initialization parameters more contained to the object itself, allowing you to use less code overall and avoid object reference times that could be avoided, as well as makes it easier to modify in the future if you need to make changes. Separation of Concern. Do it.

And anything that has a reference to a player needs to mark that reference tmp. Always. You have no idea how important that is.

var
list/coinlist = new

proc/globalLoop()
while(1)
for(var/obj/coin/coin in coinlist)
if(coin.target)
coin.gotoTarget()
else
del coin
sleep(world.tick_lag)

obj
coin
icon = 'Money.dmi'
density = 0
var value
var/tmp/mob/combat/player/target
var/rank
var/stepcount
bronze
icon_state = "bronze"
rank=1
silver
icon_state = "silver"
rank=2
gold
icon_state = "gold"
rank=3
diamond
icon_state = "diamond"
rank=4
glide_size = 2

proc/gotoTarget()
if(target.z!=z || ++stepcount>35 || bounds_dist(src,target)<0)
target.addCoin(rank,value)
del src
else
step_towards(src,target)

New(loc,value,target)
pixel_x += rand(-5,5)
pixel_y += rand(-5,5)
src.value = value
src.target = target
coinlist += src
..()

Del()
loc = null
coinlist -= src
..()

proc/generateCoins(rank,count,mobloc,atom/target)
var/cointype, obj/coin/coin, value
switch(rank)
if(1)
cointype = /obj/coin/bronze
if(2)
cointype = /obj/coin/silver
if(3)
cointype = /obj/coin/gold
if(4)
cointype = /obj/coin/diamond

while(count>0)
value = min(count,333)
count -= value
coin = new cointype(mobloc,value,target)