I have spent hours trying to figure this one out, and it is driving me nuts.
This script is to allow a choice of spell via keypress and do damage to a mob.
The problem is trying to display the mobs health in real time. For some reason when I try to update the string, it just pops the spiders new health onto the end of my string. For example: Spider has 5 health, I use a spell that does 1 damage, and instead of updating the string to say "Spider Health: 4" it scrambles the two and says "Spider Health: 54". I am sure this is something simple and stupid I am doing wrong, but I am at my wits end. Below is the code for your perusal, mockery, and hopefully help!
--------------------------------------
plotscript, chooseattackspider, begin
$8="Spider Atk:5"
$9="Spider Def:5"
$10="Spider Base Atk:0"
$4="Spider Health:"
$11= "Choose your attack"
begin
show string at (8,178,0)
show string at (9,178,10)
show string at (4,178,125)
show string at (10,178,20)
append number(4, spidermobhealth)
end
suspend player
show string at (11,150,150)
while (true) do,begin
wait (2)
if (key is pressed(Key:1) && knows spell(hero:protagon,atk:Ice dart)) then
(spidermobhealth-=1
(append number (4,spidermobhealth))
hide string (11)
show text box (60)
wait for scancode(key:space)
(resume player
exit script))
else
if (key is pressed(Key:2) && knows spell(hero:protagon,atk:Fire ball)) then
(spidermobhealth-=2
(append number (4,spidermobhealth))
hide string (11)
show text box (61)
wait for scancode(key:space)
(resume player
exit script))
else
if (key is pressed(Key:Space)) then
(hide string(11)
show text box(20)
exit script)
end
---------------------------------------
Thanks again in advance.
I think your problem is the command "AppendNumber". AppendNumber just tacks that number onto the end of the string. So if you were to have a string that was say, "Numbers" and you ran "Append Number (1,Numbers)" the result would be a string that says "Numbers1". If you ran it again, you would have "Numbers11" not "Numbers2". Not sure what command you should use instead, but I'm pretty surei t's not AppendNumber.
Maybe if you cleared the string each time like... reset it to "Spider Health:" before you append the number it would work?
Maybe if you cleared the string each time like... reset it to "Spider Health:" before you append the number it would work?
gizmog is right i think.
"replacechar" will replace a character in the string with an ascii code and thats what i would use.
but to not change your script any, you can use "clearstring" before "appendstring". that will empty the string your trying to append to and solve your problems
something like..
clearstring (4)
appendnumber (4, spidermobhealth)
"replacechar" will replace a character in the string with an ascii code and thats what i would use.
but to not change your script any, you can use "clearstring" before "appendstring". that will empty the string your trying to append to and solve your problems
something like..
clearstring (4)
appendnumber (4, spidermobhealth)
In order to update string 4, do
Why do you have lots of unnecessary (though harmless) brackets around lines, such as "(append number (4,spidermobhealth)) ".
Also, I recommend using "wait(1)" instead of "wait(2)" in your loop. Waiting for two ticks means that if you press a key quickly it could be missed.
Code:
$4="Spider Health:"
append number(4, spidermobhealth)
append number(4, spidermobhealth)
Why do you have lots of unnecessary (though harmless) brackets around lines, such as "(append number (4,spidermobhealth)) ".
Also, I recommend using "wait(1)" instead of "wait(2)" in your loop. Waiting for two ticks means that if you press a key quickly it could be missed.
Thanks so much guys. That was exactly what I needed TMC. The brackets are there because this is my first plotscript game attempt and I have little clue what I am doing. I thought maybe it would affect the order of operations and return the result I wanted. Works PERFECTLY now. You are my hero.
As for the wait command, it is set to (2) as the regular weapon based attacks are run by a seperate script where you press space to move to each next step. I found at wait(1) I was accidentally skipping past the above script from my last space bar press.
Thanks again!
As for the wait command, it is set to (2) as the regular weapon based attacks are run by a seperate script where you press space to move to each next step. I found at wait(1) I was accidentally skipping past the above script from my last space bar press.
Thanks again!
Hey guys. Back again with another puzzle for ya.
I am attempting a script where you can fire off projectiles in real time and have them destroy enemies on map. The problem is I want the enemy to also be able to fire off these projectiles at you... the only way I have found to do this in my limited scripting knowledge is with while(true) loops. The problem is, only one of these seems to be able to run at once. So either I am able to shoot, and the enemy is not..or the enemy is able to shoot and I am not...depending on the order these loops are called. Is there any way around this? Attached again is my code. The idea is to be able to set up multiple "guns" with different behaviours based on this code...
THANKS GUISE!!!
I am attempting a script where you can fire off projectiles in real time and have them destroy enemies on map. The problem is I want the enemy to also be able to fire off these projectiles at you... the only way I have found to do this in my limited scripting knowledge is with while(true) loops. The problem is, only one of these seems to be able to run at once. So either I am able to shoot, and the enemy is not..or the enemy is able to shoot and I am not...depending on the order these loops are called. Is there any way around this? Attached again is my code. The idea is to be able to set up multiple "guns" with different behaviours based on this code...
THANKS GUISE!!!
Code:
include, plotscr.hsd
include, boolit.hsi
include, scancode.hsi
global variable (0,d)
global variable(1,mobd)
plotscript, shoot, begin
#enemy attack1 <----------THIS IS COMMENTED BECAUSE IF IT RUNS, I CANNOT ATTACK!
put camera (20,20)
variable (x,y)
while (true), do, begin
wait (1)
if (key is pressed (key:f)) then
(x:=hero X(me)
y:=hero Y(me)
d:=hero direction(me)
if (d==north) then(decrement(y))
if (d==south) then(increment(y))
if (d==west) then(decrement(x))
if (d==east) then(increment(x))
create NPC(5,x,y,d)
set NPC obstructs (5, false)
set NPC ignores walls (5, true)
walk NPC (5,d,15)
check for enemy hit)
end
end
#------------------------------------
plotscript, check for enemy hit, begin
variable (BULLETTIMER)
BULLETTIMER:=(12)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
variable (bulletx,bullety)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
while (true), do, begin
wait(1)
bulletx:=NPC X(5)
bulletY:=NPC Y(5)
enemypos1x:=NPC X(enemy1)
enemypos1y:=NPC Y(enemy1)
enemypos2x:=NPC X(enemy2)
enemypos2y:=NPC Y(enemy2)
enemypos3x:=NPC X(enemy3)
enemypos3y:=NPC Y(enemy3)
if (bulletx == enemypos1x && bullet y == enemypos1y) then
(destroy NPC (enemy1)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos2x && bullet y == enemypos2y) then
(destroy NPC (enemy2)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos3x && bullet y == enemypos3y) then
(destroy NPC (enemy3)
destroy NPC (5)
exit script)
else
(BULLETTIMER-=1)
if (BULLETTIMER<<1) then
(destroy NPC (5)
exit script)
else
end
end
#-------------------------------------
plotscript, enemy attack1, begin
put camera (20,20)
variable (mobx,moby)
while (true), do, begin
wait (1)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
mobx:=NPC X(enemy1)
moby:=NPC Y(enemy1)
mobd:=NPC direction(enemy1)
if (mobd==north) then(decrement(moby))
if (mobd==south) then(increment(moby))
if (mobd==west) then(decrement(mobx))
if (mobd==east) then(increment(mobx))
create NPC(6,mobx,moby,mobd)
set NPC obstructs (6, false)
set NPC ignores walls (6, true)
walk NPC (6,mobd,15)
check for player hit)
end
#----------------------------
plotscript, check for player hit, begin
variable (MOBBULLETTIMER)
MOBBULLETTIMER:=(12)
variable (playerposx,playerposy)
variable (mobbullet1x,mobbullet1y,mobbullet2x,mobbullet2y,mobbullet3x,mobbullet3y)
while (true), do, begin
wait(1)
playerposx:=hero x(me)
playerposy:=hero y(me)
mobbullet1x:=NPC X(6)
mobbullet1y:=NPC Y(6)
mobbullet2x:=NPC X(6)
mobbullet2y:=NPC Y(6)
mobbullet3x:=NPC X(6)
mobbullet3y:=NPC Y(6)
if (mobbullet1x == playerposx && mobbullet1y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet2x == playerposx && mobbullet2y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet3x == playerposx && mobbullet3y == playerposy) then
(show text box (10)
exit script)
else
(MOBBULLETTIMER-=1)
if (MOBBULLETTIMER<<1) then
(destroy NPC (6)
exit script)
else
end
end
include, plotscr.hsd
include, boolit.hsi
include, scancode.hsi
global variable (0,d)
global variable(1,mobd)
plotscript, shoot, begin
#enemy attack1 <----------THIS IS COMMENTED BECAUSE IF IT RUNS, I CANNOT ATTACK!
put camera (20,20)
variable (x,y)
while (true), do, begin
wait (1)
if (key is pressed (key:f)) then
(x:=hero X(me)
y:=hero Y(me)
d:=hero direction(me)
if (d==north) then(decrement(y))
if (d==south) then(increment(y))
if (d==west) then(decrement(x))
if (d==east) then(increment(x))
create NPC(5,x,y,d)
set NPC obstructs (5, false)
set NPC ignores walls (5, true)
walk NPC (5,d,15)
check for enemy hit)
end
end
#------------------------------------
plotscript, check for enemy hit, begin
variable (BULLETTIMER)
BULLETTIMER:=(12)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
variable (bulletx,bullety)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
while (true), do, begin
wait(1)
bulletx:=NPC X(5)
bulletY:=NPC Y(5)
enemypos1x:=NPC X(enemy1)
enemypos1y:=NPC Y(enemy1)
enemypos2x:=NPC X(enemy2)
enemypos2y:=NPC Y(enemy2)
enemypos3x:=NPC X(enemy3)
enemypos3y:=NPC Y(enemy3)
if (bulletx == enemypos1x && bullet y == enemypos1y) then
(destroy NPC (enemy1)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos2x && bullet y == enemypos2y) then
(destroy NPC (enemy2)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos3x && bullet y == enemypos3y) then
(destroy NPC (enemy3)
destroy NPC (5)
exit script)
else
(BULLETTIMER-=1)
if (BULLETTIMER<<1) then
(destroy NPC (5)
exit script)
else
end
end
#-------------------------------------
plotscript, enemy attack1, begin
put camera (20,20)
variable (mobx,moby)
while (true), do, begin
wait (1)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
mobx:=NPC X(enemy1)
moby:=NPC Y(enemy1)
mobd:=NPC direction(enemy1)
if (mobd==north) then(decrement(moby))
if (mobd==south) then(increment(moby))
if (mobd==west) then(decrement(mobx))
if (mobd==east) then(increment(mobx))
create NPC(6,mobx,moby,mobd)
set NPC obstructs (6, false)
set NPC ignores walls (6, true)
walk NPC (6,mobd,15)
check for player hit)
end
#----------------------------
plotscript, check for player hit, begin
variable (MOBBULLETTIMER)
MOBBULLETTIMER:=(12)
variable (playerposx,playerposy)
variable (mobbullet1x,mobbullet1y,mobbullet2x,mobbullet2y,mobbullet3x,mobbullet3y)
while (true), do, begin
wait(1)
playerposx:=hero x(me)
playerposy:=hero y(me)
mobbullet1x:=NPC X(6)
mobbullet1y:=NPC Y(6)
mobbullet2x:=NPC X(6)
mobbullet2y:=NPC Y(6)
mobbullet3x:=NPC X(6)
mobbullet3y:=NPC Y(6)
if (mobbullet1x == playerposx && mobbullet1y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet2x == playerposx && mobbullet2y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet3x == playerposx && mobbullet3y == playerposy) then
(show text box (10)
exit script)
else
(MOBBULLETTIMER-=1)
if (MOBBULLETTIMER<<1) then
(destroy NPC (6)
exit script)
else
end
end
Right now there is no support for script multitasking. That is planned for the future, but I am not sure when.
Fortunately there is a trick that lets you run multiple loops at the same time.
Have a look at the "set timer" command in the plotscripting dictionary.
Instead of using a while/loop and wait commands, you can loop like this:
I know this is a lot more complicated than a while loop, but you can have as many timers running simultaneously as you want, and as long as there are no "wait" commands in them, they will not block each other.
Fortunately there is a trick that lets you run multiple loops at the same time.
Have a look at the "set timer" command in the plotscripting dictionary.
Instead of using a while/loop and wait commands, you can loop like this:
Code:
define constant(0, example timer)
plotscript, start example loop, begin
# create the projectile here
set timer(example timer, 0, 1, @example loop)
end
script, example loop, begin
variable(keep looping)
keep looping := True
#
# update the projectile here
#
if(keep looping) then(
set timer(example timer, 0, 1, @example loop)
)
end
define constant(0, example timer)
plotscript, start example loop, begin
# create the projectile here
set timer(example timer, 0, 1, @example loop)
end
script, example loop, begin
variable(keep looping)
keep looping := True
#
# update the projectile here
#
if(keep looping) then(
set timer(example timer, 0, 1, @example loop)
)
end
I know this is a lot more complicated than a while loop, but you can have as many timers running simultaneously as you want, and as long as there are no "wait" commands in them, they will not block each other.
I appreciate the quick response! Unfortunately I tried (and failed) to integrate that into my script. I made sure all wait commands were removed, but I am obviously missing something else that needs to be shifted around or omitted. Pretty sure I just made a mess! The main problem is my attack key (F) doesn't seem to do squat anymore! I swear the more I look at this code the more alien it appears!
My updated script... don't laugh!!:
My updated script... don't laugh!!:
Code:
include, plotscr.hsd
include, boolit.hsi
include, scancode.hsi
global variable (0,d)
global variable(1,mobd)
define constant (0, playershottime)
define constant (1,mobshottime)
plotscript, start check for enemy hit, begin
start attack and check for player hit
put camera (20,20)
variable (x,y)
if (key is pressed (key:f)) then
(x:=hero X(me)
y:=hero Y(me)
d:=hero direction(me)
if (d==north) then(decrement(y))
if (d==south) then(increment(y))
if (d==west) then(decrement(x))
if (d==east) then(increment(x))
create NPC(5,x,y,d)
set NPC obstructs (5, false)
set NPC ignores walls (5, true)
walk NPC (5,d,15)
end
set timer (playershottime,0,1, @check for enemy hit)
end
#------------------------------------
plotscript, check for enemy hit, begin
variable(keep looping)
keep looping:=true
variable (BULLETTIMER)
BULLETTIMER:=(12)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
variable (bulletx,bullety)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
bulletx:=NPC X(5)
bulletY:=NPC Y(5)
enemypos1x:=NPC X(enemy1)
enemypos1y:=NPC Y(enemy1)
enemypos2x:=NPC X(enemy2)
enemypos2y:=NPC Y(enemy2)
enemypos3x:=NPC X(enemy3)
enemypos3y:=NPC Y(enemy3)
if (bulletx == enemypos1x && bullet y == enemypos1y) then
(destroy NPC (enemy1)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos2x && bullet y == enemypos2y) then
(destroy NPC (enemy2)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos3x && bullet y == enemypos3y) then
(destroy NPC (enemy3)
destroy NPC (5)
exit script)
else
(BULLETTIMER-=1)
if (BULLETTIMER<<1) then
(destroy NPC (5)
exit script)
if (keep looping) then
(set timer(playershottime,0,1,@check for enemy hit)
end
end
#-------------------------------------
plotscript, start attack and check for player hit, begin
put camera (20,20)
variable (mobx,moby)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
mobx:=NPC X(enemy1)
moby:=NPC Y(enemy1)
mobd:=NPC direction(enemy1)
if (mobd==north) then(decrement(moby))
if (mobd==south) then(increment(moby))
if (mobd==west) then(decrement(mobx))
if (mobd==east) then(increment(mobx))
create NPC(6,mobx,moby,mobd)
set NPC obstructs (6, false)
set NPC ignores walls (6, true)
walk NPC (6,mobd,15)
set timer (mobshottime,1,1, @attack and check for player hit)
end
#----------------------------
plotscript, attack and check for player hit, begin
variable (keep looping)
keep looping := true
variable (MOBBULLETTIMER)
MOBBULLETTIMER:=(12)
variable (playerposx,playerposy)
variable (mobbullet1x,mobbullet1y,mobbullet2x,mobbullet2y,mobbullet3x,mobbullet3y)
playerposx:=hero x(me)
playerposy:=hero y(me)
mobbullet1x:=NPC X(6)
mobbullet1y:=NPC Y(6)
mobbullet2x:=NPC X(6)
mobbullet2y:=NPC Y(6)
mobbullet3x:=NPC X(6)
mobbullet3y:=NPC Y(6)
if (mobbullet1x == playerposx && mobbullet1y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet2x == playerposx && mobbullet2y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet3x == playerposx && mobbullet3y == playerposy) then
(show text box (10)
exit script)
else
(MOBBULLETTIMER-=1)
if (MOBBULLETTIMER<<1) then
(destroy NPC (6)
if (keep looping) then
(set timer(mobshottime,1,1, @attack and check for player hit)
end
end
end
include, plotscr.hsd
include, boolit.hsi
include, scancode.hsi
global variable (0,d)
global variable(1,mobd)
define constant (0, playershottime)
define constant (1,mobshottime)
plotscript, start check for enemy hit, begin
start attack and check for player hit
put camera (20,20)
variable (x,y)
if (key is pressed (key:f)) then
(x:=hero X(me)
y:=hero Y(me)
d:=hero direction(me)
if (d==north) then(decrement(y))
if (d==south) then(increment(y))
if (d==west) then(decrement(x))
if (d==east) then(increment(x))
create NPC(5,x,y,d)
set NPC obstructs (5, false)
set NPC ignores walls (5, true)
walk NPC (5,d,15)
end
set timer (playershottime,0,1, @check for enemy hit)
end
#------------------------------------
plotscript, check for enemy hit, begin
variable(keep looping)
keep looping:=true
variable (BULLETTIMER)
BULLETTIMER:=(12)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
variable (bulletx,bullety)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
bulletx:=NPC X(5)
bulletY:=NPC Y(5)
enemypos1x:=NPC X(enemy1)
enemypos1y:=NPC Y(enemy1)
enemypos2x:=NPC X(enemy2)
enemypos2y:=NPC Y(enemy2)
enemypos3x:=NPC X(enemy3)
enemypos3y:=NPC Y(enemy3)
if (bulletx == enemypos1x && bullet y == enemypos1y) then
(destroy NPC (enemy1)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos2x && bullet y == enemypos2y) then
(destroy NPC (enemy2)
destroy NPC (5)
exit script)
else
if (bulletx == enemypos3x && bullet y == enemypos3y) then
(destroy NPC (enemy3)
destroy NPC (5)
exit script)
else
(BULLETTIMER-=1)
if (BULLETTIMER<<1) then
(destroy NPC (5)
exit script)
if (keep looping) then
(set timer(playershottime,0,1,@check for enemy hit)
end
end
#-------------------------------------
plotscript, start attack and check for player hit, begin
put camera (20,20)
variable (mobx,moby)
variable (enemy1,enemy2,enemy3)
variable (enemypos1x,enemypos1y,enemypos2x,enemypos2y,enemypos3x,enemypos3y)
enemy1:=NPC reference (1,)
enemy2:=NPC reference (2,)
enemy3:=NPC reference (3,)
mobx:=NPC X(enemy1)
moby:=NPC Y(enemy1)
mobd:=NPC direction(enemy1)
if (mobd==north) then(decrement(moby))
if (mobd==south) then(increment(moby))
if (mobd==west) then(decrement(mobx))
if (mobd==east) then(increment(mobx))
create NPC(6,mobx,moby,mobd)
set NPC obstructs (6, false)
set NPC ignores walls (6, true)
walk NPC (6,mobd,15)
set timer (mobshottime,1,1, @attack and check for player hit)
end
#----------------------------
plotscript, attack and check for player hit, begin
variable (keep looping)
keep looping := true
variable (MOBBULLETTIMER)
MOBBULLETTIMER:=(12)
variable (playerposx,playerposy)
variable (mobbullet1x,mobbullet1y,mobbullet2x,mobbullet2y,mobbullet3x,mobbullet3y)
playerposx:=hero x(me)
playerposy:=hero y(me)
mobbullet1x:=NPC X(6)
mobbullet1y:=NPC Y(6)
mobbullet2x:=NPC X(6)
mobbullet2y:=NPC Y(6)
mobbullet3x:=NPC X(6)
mobbullet3y:=NPC Y(6)
if (mobbullet1x == playerposx && mobbullet1y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet2x == playerposx && mobbullet2y == playerposy) then
(show text box (10)
exit script)
else
if (mobbullet3x == playerposx && mobbullet3y == playerposy) then
(show text box (10)
exit script)
else
(MOBBULLETTIMER-=1)
if (MOBBULLETTIMER<<1) then
(destroy NPC (6)
if (keep looping) then
(set timer(mobshottime,1,1, @attack and check for player hit)
end
end
end
Firstly, BULLETTIMER and MOBBULLETTIMER need to be converted into global variables, because values of local "variable"s are remembered when a script is run again. You should set the initial value of the global variable in the appropriate "start X" script.
Also you should use "set timer (id, 0, 1, @scriptname)", not "set timer (id, 1, 1, @scriptname)". The latter calls the script after two ticks instead of one (yes, it's very confusing).
You mixed up your shoot script. You placed "set timer (playershottime,0,1, @check for enemy hit) " in the wrong place.
HOWEVER, I would not use "set timer" at all for this. You could, but as you can see it's already a mess, and it's going to get far worse once you have 3 enemies and 4 projectiles on screen, because that will require copy-pasting all your scripts multiple times. Instead use one "main loop" and call "check for player hit" etc. every tick from that while loop if appropriate. In fact it's generally little work to convert timer-based scripts to main-loop based ones.
So your main loop and scripts could look like this (I haven't converted all the scripts, the rest is left for you). Notice that you need one global variable per projectile. Don't copy paste code, instead give arguments to a script and reuse it. In this case that means using of "read global" and "write global" which is slightly advanced, but I'm sure you'll understand it. (Actually, using "NPC extra" data instead of global variables would be quite natural.) Also, in future indent your code properly as I've done!
Also you should use "set timer (id, 0, 1, @scriptname)", not "set timer (id, 1, 1, @scriptname)". The latter calls the script after two ticks instead of one (yes, it's very confusing).
You mixed up your shoot script. You placed "set timer (playershottime,0,1, @check for enemy hit) " in the wrong place.
HOWEVER, I would not use "set timer" at all for this. You could, but as you can see it's already a mess, and it's going to get far worse once you have 3 enemies and 4 projectiles on screen, because that will require copy-pasting all your scripts multiple times. Instead use one "main loop" and call "check for player hit" etc. every tick from that while loop if appropriate. In fact it's generally little work to convert timer-based scripts to main-loop based ones.
So your main loop and scripts could look like this (I haven't converted all the scripts, the rest is left for you). Notice that you need one global variable per projectile. Don't copy paste code, instead give arguments to a script and reuse it. In this case that means using of "read global" and "write global" which is slightly advanced, but I'm sure you'll understand it. (Actually, using "NPC extra" data instead of global variables would be quite natural.) Also, in future indent your code properly as I've done!
Code:
global variable (
1, player bullet timer
2, mob1 bullet timer
3, mob2 bullet timer
4, mob3 bullet timer
)
plotscript, main loop, begin
put camera (20,20)
while (true), do, begin
wait (1)
if (npc copy count(5) == 0) then (
# Player can only shoot if there's not already a projectile on screen
if (key is pressed (key:f)) then (shoot)
) else (
check for enemy hit
)
if (npc copy count(6) == 0) then (
# the enemy can only shoot if it doesn't already have a projectile
# You can reuse the "enemy attack" script for different enemies.
# 1 is the enemy NPC, 6 is the projectile NPC, @mob1 bullet timer is
# the ID of the global variable.
enemy attack (1, 6, @mob1 bullet timer)
) else (
check for player hit (6, @mob1 bullet timer)
)
end
end
script, shoot, begin
variable (x,y)
x:=hero X(me)
y:=hero Y(me)
d:=hero direction(me)
if (d==north) then(decrement(y))
if (d==south) then(increment(y))
if (d==west) then(decrement(x))
if (d==east) then(increment(x))
create NPC(5,x,y,d)
set NPC obstructs (5, false)
set NPC ignores walls (5, true)
walk NPC (5,d,15)
end
plotscript, enemy attack, mob npc, bullet npc, bullet timer id, begin
variable (mobx,moby)
variable (enemy)
enemy:=NPC reference (mob npc)
mobx:=NPC X(enemy)
moby:=NPC Y(enemy)
mobd:=NPC direction(enemy)
if (mobd==north) then(decrement(moby))
if (mobd==south) then(increment(moby))
if (mobd==west) then(decrement(mobx))
if (mobd==east) then(increment(mobx))
create NPC(bullet npc,mobx,moby,mobd)
set NPC obstructs (bullet npc, false)
set NPC ignores walls (bullet npc, true)
walk NPC (bullet npc, mobd, 15)
write global (bullet timer id, 12) # equivalent to "mob1 bullet timer := 12"
end
#----------------------------
plotscript, check for player hit, bullet npc, bullet timer id, begin
variable (playerposx,playerposy)
variable (mobbulletx,mobbullety)
playerposx:=hero x(me)
playerposy:=hero y(me)
mobbulletx:=NPC X(bullet npc)
mobbullety:=NPC Y(bullet npc)
if (mobbulletx == playerposx && mobbullety == playerposy) then (
show text box (10)
) else (
variable (MOBBULLETTIMER)
MOBBULLETTIMER := read global (bullet timer id) #equivalent to "MOBBULLETTIMER := mob1 bullet timer"
MOBBULLETTIMER -= 1
write global (bullet timer id, MOBBULLETTIMER)
if (MOBBULLETTIMER<<1) then (
destroy NPC (bullet npc)
)
)
end
global variable (
1, player bullet timer
2, mob1 bullet timer
3, mob2 bullet timer
4, mob3 bullet timer
)
plotscript, main loop, begin
put camera (20,20)
while (true), do, begin
wait (1)
if (npc copy count(5) == 0) then (
# Player can only shoot if there's not already a projectile on screen
if (key is pressed (key:f)) then (shoot)
) else (
check for enemy hit
)
if (npc copy count(6) == 0) then (
# the enemy can only shoot if it doesn't already have a projectile
# You can reuse the "enemy attack" script for different enemies.
# 1 is the enemy NPC, 6 is the projectile NPC, @mob1 bullet timer is
# the ID of the global variable.
enemy attack (1, 6, @mob1 bullet timer)
) else (
check for player hit (6, @mob1 bullet timer)
)
end
end
script, shoot, begin
variable (x,y)
x:=hero X(me)
y:=hero Y(me)
d:=hero direction(me)
if (d==north) then(decrement(y))
if (d==south) then(increment(y))
if (d==west) then(decrement(x))
if (d==east) then(increment(x))
create NPC(5,x,y,d)
set NPC obstructs (5, false)
set NPC ignores walls (5, true)
walk NPC (5,d,15)
end
plotscript, enemy attack, mob npc, bullet npc, bullet timer id, begin
variable (mobx,moby)
variable (enemy)
enemy:=NPC reference (mob npc)
mobx:=NPC X(enemy)
moby:=NPC Y(enemy)
mobd:=NPC direction(enemy)
if (mobd==north) then(decrement(moby))
if (mobd==south) then(increment(moby))
if (mobd==west) then(decrement(mobx))
if (mobd==east) then(increment(mobx))
create NPC(bullet npc,mobx,moby,mobd)
set NPC obstructs (bullet npc, false)
set NPC ignores walls (bullet npc, true)
walk NPC (bullet npc, mobd, 15)
write global (bullet timer id, 12) # equivalent to "mob1 bullet timer := 12"
end
#----------------------------
plotscript, check for player hit, bullet npc, bullet timer id, begin
variable (playerposx,playerposy)
variable (mobbulletx,mobbullety)
playerposx:=hero x(me)
playerposy:=hero y(me)
mobbulletx:=NPC X(bullet npc)
mobbullety:=NPC Y(bullet npc)
if (mobbulletx == playerposx && mobbullety == playerposy) then (
show text box (10)
) else (
variable (MOBBULLETTIMER)
MOBBULLETTIMER := read global (bullet timer id) #equivalent to "MOBBULLETTIMER := mob1 bullet timer"
MOBBULLETTIMER -= 1
write global (bullet timer id, MOBBULLETTIMER)
if (MOBBULLETTIMER<<1) then (
destroy NPC (bullet npc)
)
)
end
By the way, in case anyone cares, you can get your less-thans and greater-thans to post correctly by checking "Disable HTML in this post."
Without the option selected, the above code will show up like this:
Mega Tact v1.1
Super Penguin Chef
Wizard Blocks
Code:
if (x << y && y >> x) then (test)
Without the option selected, the above code will show up like this:
Code:
if (x <<y>> x) then (test)
Mega Tact v1.1
Super Penguin Chef
Wizard Blocks
thanks for the help, you guys are great!
I am getting errors by the time I hit the first "check for enemy hit" part of the script. It is telling me "checkforenemy hit has no default for missing arguement 1".
I tried setting it up like the "check for player hit" trigger by adding
which spits back that checkforenemy now has no argument 3.
I appreciate your faith in thinking I'd understand the code...and for taking the time to comment out the bits so I could better understand them... but I think I may be in over my head with this project!!
I am getting errors by the time I hit the first "check for enemy hit" part of the script. It is telling me "checkforenemy hit has no default for missing arguement 1".
I tried setting it up like the "check for player hit" trigger by adding
Code:
"(5, @player bullet timer) "
which spits back that checkforenemy now has no argument 3.
I appreciate your faith in thinking I'd understand the code...and for taking the time to comment out the bits so I could better understand them... but I think I may be in over my head with this project!!
OK, if you want to make "check for player hit" take those two arguments, that's fine. But make sure you specified the arguments correctly in the header of the script/plotscript. Sounds like you copy pasted that header from another script so it has an extra argument.
I suggest reading Making a custom combat engine . It seems like a good follow up to the Plotscripting Tutorial, teaching how to actually piece things together.
I suggest reading Making a custom combat engine . It seems like a good follow up to the Plotscripting Tutorial, teaching how to actually piece things together.
Hi again guys. Got another question for ya. Is it feasible to layer several npcs over the hero and have them move in sync with the hero? This could be used, for example, to have different pieces of armor show up on your walkabout without having to create thousands of walkabouts to account for all the possible armor combinations. How would one go about doing this if so? Thanks again.
Hello,
I think it's not possible with NPCs, but with slices.
Slices are pieces of gaphics, that can be alted by using scripts.
I've never used them, so I can't tell you more, but there's a tutorial in the wiki:
http://rpg.hamsterrepublic.com/ohrrpgce/Slices_Tutorial#Layering
I think it's not possible with NPCs, but with slices.
Slices are pieces of gaphics, that can be alted by using scripts.
I've never used them, so I can't tell you more, but there's a tutorial in the wiki:
http://rpg.hamsterrepublic.com/ohrrpgce/Slices_Tutorial#Layering



