Post new topic    
Page 1, 2  »
Help with script please! 
 PostMon Apr 01, 2013 2:38 am
Send private message Reply with quote
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.
Metal King Slime
Send private message
 
 PostMon Apr 01, 2013 4:15 am
Send private message Reply with quote
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?
Red Slime
Send private message
 
 PostMon Apr 01, 2013 4:34 am
Send private message Reply with quote
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)
Metal King Slime
Send private message
 
 PostMon Apr 01, 2013 7:48 am
Send private message Reply with quote
In order to update string 4, do

Code:
$4="Spider Health:"
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.
 
 PostMon Apr 01, 2013 8:20 pm
Send private message Reply with quote
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!
 
 PostSat Apr 06, 2013 10:42 pm
Send private message Reply with quote
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!!!

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
Liquid Metal King Slime
Send private message
 
 PostSat Apr 06, 2013 11:04 pm
Send private message Reply with quote
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:

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



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.
 
 PostSat Apr 06, 2013 11:49 pm
Send private message Reply with quote
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!!:

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
Metal King Slime
Send private message
 
 PostSun Apr 07, 2013 3:19 am
Send private message Reply with quote
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!

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
Super Slime
Send private message
 
 PostSun Apr 07, 2013 3:27 am
Send private message Reply with quote
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."

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
Metal King Slime
Send private message
 
 PostSun Apr 07, 2013 4:34 am
Send private message Reply with quote
A solution at last!
 
 PostSun Apr 07, 2013 5:07 am
Send private message Reply with quote
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

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!!
Metal King Slime
Send private message
 
 PostSun Apr 07, 2013 6:17 am
Send private message Reply with quote
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.
 
 PostFri May 24, 2013 5:43 am
Send private message Reply with quote
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.
Metal Slime
Send private message
 
 PostFri May 24, 2013 9:21 am
Send private message Reply with quote
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
Display posts from previous:
Page 1, 2  »