Canceled Knights & Dragons: The Endless Quest - improved version

Project is halted prior to completion and will not receive further updates.
Are you planning more freespecials?
In my opinion, upgrading hp/defense/offense is less meaningful than adding new moves.

The reason:

1. hp/defense/offense only affect how fast you beat enemies or how fast you are overwhelmed by enemies. Basically, if you have 100 HP, the enemies have 10 average damage, when you reach 200 HP, harder enemies may deal 20 damage. That is what happens in Knights of the Round.
2. hp/defense/offense barely affect visual effects, something you even don't notice without those numbers.
3. they don't affect gameplay much, making the game less interesting after some levels.

Obtaining a new move usually means you have new strategies to use, more reason to burn or save your mp. Also, a new motivation to gain levels (because 10 HP doesn't means too much to me, but a new move....). For example, the fighter can have only the basic hack'n slash moves at level 1, when he reaches lv 3, he gains a charge attack. This can be easily done by some ticks, for example, redirect it to a heavy attack if your level is below 3.
 
utunnels said:
Are you planning more freespecials?
In my opinion, upgrading hp/defense/offense is less meaningful than adding new moves.

The reason:

1. hp/defense/offense only affect how fast you beat enemies or how fast you are overwhelmed by enemies. Basically, if you have 100 HP, the enemies have 10 average damage, when you reach 200 HP, harder enemies may deal 20 damage. That is what happens in Knights of the Round.
2. hp/defense/offense barely affect visual effects, something you even don't notice without those numbers.
3. they don't affect gameplay much, making the game less interesting after some levels.

Obtaining a new move usually means you have new strategies to use, more reason to burn or save your mp. Also, a new motivation to gain levels (because 10 HP doesn't means too much to me, but a new move....). For example, the fighter can have only the basic hack'n slash moves at level 1, when he reaches lv 3, he gains a charge attack.

yea i was thinking about this, i was doing this thing with my dungeon fighter mod.

This can be easily done by some ticks, for example, redirect it to a heavy attack if your level is below 3.

you use some script to do this? i usually use simply mp cost.
for example, if the fighter starts with 10 mp, he can't use the freespecialN that, let's say, cost 15. but when he level up and reach the 15 mp, the move of course become aviable.
 
That works. But if you want a low cost move, you need to add mp back.

For example, your character has 120mp, the move costs 110mp, but you want it to only cost 10mp, then you need to add 100mp after the move is execued.


You can also change energycost via script directly, if you use nosame.


changeentityproperty(ent, "energycost", "cost", openborconstant("ANI_FREESPECIAL3"),  100):
 
utunnels said:
That works. But if you want a low cost move, you need to add mp back.

For example, your character has 120mp, the move costs 110mp, but you want it to only cost 10mp, then you need to add 100mp after the move is execued.


You can also change energycost via script directly, if you use nosame.


changeentityproperty(ent, "energycost", "cost", openborconstant("ANI_FREESPECIAL3"),  100):

actually i've changed the starting hp and mp, so now the chars will start with no more than a dozens of HP/MP, so i thinked i would not have needed this.
but your idea for adding the mp it's cool, where and how can i implement this script?
 
You can use that in lvup.c, along with the hp/mp logic.

But you are right, your previous idea is easier, because this solution has a problem that you have to specific all animations, unless you use set up the animations in exactly the same way for all the characters. So it could be just a back-up plan.
 
just one thing: when you say:
For example, your character has 120mp, the move costs 110mp, but you want it to only cost 10mp, then you need to add 100mp after the move is execued.

how can i add the 100 mp after the move is executed? there is some command that make you regain mp?
 
oh right, i forgot that trick. it works perfectly, except for the freespecial that already have a similiar script, for example:

anim freespecial2
energycost 40
mponly  1
shadowcoords 218 198
loop 0
offset    225 198
bbox 0 0 0 0

delay 1
sound  data/sounds/csw.wav
frame data/chars/paladin/guard01.gif
@script
if(frame==1){
    void self = getlocalvar("self");

    changeentityproperty(self, "mp", 35);
}
@end_script
delay 1
frame data/chars/paladin/guard01.gif
delay 2
frame data/chars/paladin/guard10.gif
frame data/chars/paladin/guard02.gif
frame data/chars/paladin/guard11.gif
frame data/chars/paladin/guard03.gif
frame data/chars/paladin/guard12.gif
frame data/chars/paladin/guard04.gif
frame data/chars/paladin/guard13.gif
frame data/chars/paladin/guard01.gif
frame data/chars/paladin/guard10.gif
frame data/chars/paladin/guard02.gif
frame data/chars/paladin/guard11.gif
frame data/chars/paladin/guard03.gif
frame data/chars/paladin/guard12.gif
frame data/chars/paladin/guard04.gif
frame data/chars/paladin/guard13.gif
frame data/chars/paladin/guard01.gif
frame data/chars/paladin/guard10.gif
frame data/chars/paladin/guard02.gif
frame data/chars/paladin/guard11.gif
frame data/chars/paladin/guard03.gif
frame data/chars/paladin/guard12.gif
frame data/chars/paladin/guard04.gif
frame data/chars/paladin/guard13.gif

delay 4
frame data/chars/paladin/frsp101.gif
frame data/chars/paladin/frsp116.gif

delay 8
sound  data/sounds/cswhit.wav

@script
int iHP=0;
int i;
void ip;
int rng;
void self = getlocalvar("self");
int castx = getentityproperty(self, "x");
if(frame == 10){
for (i=0; i<=3;i++){
ip = getplayerproperty(i, "entity");
rng = getentityproperty(ip, "x")-castx;
if ((rng >0)&&(rng<100)){
iHP = getentityproperty(ip, "health");
changeentityproperty(ip, "health", iHP + 10);
}
if ((rng<0)&&(rng>-100)){
iHP = getentityproperty(ip, "health");
changeentityproperty(ip, "health", iHP + 10);
}
}
}
@end_script

frame data/chars/paladin/frsp102.gif
frame data/chars/paladin/frsp103.gif
frame data/chars/paladin/frsp104.gif
frame data/chars/paladin/frsp105.gif
frame data/chars/paladin/frsp106.gif
frame data/chars/paladin/frsp107.gif
frame data/chars/paladin/frsp108.gif
frame data/chars/paladin/frsp109.gif
frame data/chars/paladin/frsp110.gif
frame data/chars/paladin/frsp111.gif
frame data/chars/paladin/frsp112.gif
frame data/chars/paladin/frsp113.gif
frame data/chars/paladin/frsp114.gif
frame data/chars/paladin/frsp115.gif
frame data/chars/paladin/frsp116.gif
 

in wich case the engine crash and the log says it can't compile script.  ???
 
It should be something like this.

Code:
anim freespecial2
   @script
      int iHP=0;
      int i;
      void ip;
      int rng;
      void self = getlocalvar("self");
      int mp;
      int castx;
      if(frame==0){
        mp = getentityproperty(self, "mp");
        changeentityproperty(self, "mp", mp+100);
      }
      else if(frame == 10){
        castx = getentityproperty(self, "x");
         for (i=0; i<=3;i++){
            ip = getplayerproperty(i, "entity");
            if(ip) {
                rng = getentityproperty(ip, "x")-castx;
                if ((rng >0&&rng<100)||(rng<0&&rng>-100)){ 
                   iHP = getentityproperty(ip, "health");
                   changeentityproperty(ip, "health", iHP + 10);
                }
            }
         }
      }
   @end_script


   energycost 40
   mponly  1
   shadowcoords 218 198
   loop   0
    offset     225 198
   bbox   0 0 0 0

   delay   1
   sound   data/sounds/csw.wav
   frame   data/chars/paladin/guard01.gif
   delay   1
   frame   data/chars/paladin/guard01.gif
   delay   2
   frame   data/chars/paladin/guard10.gif
   frame   data/chars/paladin/guard02.gif
   frame   data/chars/paladin/guard11.gif
   frame   data/chars/paladin/guard03.gif
   frame   data/chars/paladin/guard12.gif
   frame   data/chars/paladin/guard04.gif
   frame   data/chars/paladin/guard13.gif
   frame   data/chars/paladin/guard01.gif
   frame   data/chars/paladin/guard10.gif
   frame   data/chars/paladin/guard02.gif
   frame   data/chars/paladin/guard11.gif
   frame   data/chars/paladin/guard03.gif
   frame   data/chars/paladin/guard12.gif
   frame   data/chars/paladin/guard04.gif
   frame   data/chars/paladin/guard13.gif
   frame   data/chars/paladin/guard01.gif
   frame   data/chars/paladin/guard10.gif
   frame   data/chars/paladin/guard02.gif
   frame   data/chars/paladin/guard11.gif
   frame   data/chars/paladin/guard03.gif
   frame   data/chars/paladin/guard12.gif
   frame   data/chars/paladin/guard04.gif
   frame   data/chars/paladin/guard13.gif

   delay   4
   frame   data/chars/paladin/frsp101.gif
   frame   data/chars/paladin/frsp116.gif

   delay   8
   sound   data/sounds/cswhit.wav
   frame   data/chars/paladin/frsp102.gif
   frame   data/chars/paladin/frsp103.gif
   frame   data/chars/paladin/frsp104.gif
   frame   data/chars/paladin/frsp105.gif
   frame   data/chars/paladin/frsp106.gif
   frame   data/chars/paladin/frsp107.gif
   frame   data/chars/paladin/frsp108.gif
   frame   data/chars/paladin/frsp109.gif
   frame   data/chars/paladin/frsp110.gif
   frame   data/chars/paladin/frsp111.gif
   frame   data/chars/paladin/frsp112.gif
   frame   data/chars/paladin/frsp113.gif
   frame   data/chars/paladin/frsp114.gif
   frame   data/chars/paladin/frsp115.gif
   frame   data/chars/paladin/frsp116.gif
 
utunnels, i've manage to make it works almost as i wanted.
i say "almost" because i didn't have thinked about this issue.

look at my code:
Code:
anim freespecial3
	energycost 50
	mponly  1
	jugglecost	99
	shadowcoords 218 198
	load		bomb
	custknife	bomb
	throwframe	2
	loop	0
	offset     225 198
	bbox	0 0 0 0
	sound   data/sounds/att01.wav
	
@script
      int iHP=0;
      int i;
      void ip;
      int rng;
      void self = getlocalvar("self");
      int mp;
      int castx;
      if(frame==0){
        mp = getentityproperty(self, "mp");
        changeentityproperty(self, "mp", mp+30);
      }
@end_script

	delay	8
	frame	data/chars/fighter/frsp101.gif
	delay	2
	frame	data/chars/fighter/frsp102.gif
	delay	120
	sound   data/sounds/slash01.wav
	frame	data/chars/fighter/a112.gif

this freespecial is aviable at level 3. my fighter starts with 30 mp, and since every level up he gains 10 mp, the freespecial doesn't work until level 3, when he reaches 50 mp and is finally capable of doing this freespecial.

using this script, the move should cost only 20 mp (the mp cost is 50 mp itself but the char gains immediately 30 mp with scripts, so "virtually" it works); the problem is, even if it "virtually" cost 20 and it leaves the fighter with 30 mp remaining (so in teory being capable of doing the move at least another time before finishing mp), the fighter is incapable of doing it again until he regains 50 mp.

i don't think this can be solved with scripts, at least not without re-thinking the entire thing, so i have to decide if leave it as it is (simulating the fact that the fighter is tired after doing it), or simply make the move cost 50 mp and make it stronger.
 
Yeah, that is why I said "backup" plans.

To deal with this flaw, there are several ways:

1. Leave it as it is, that is when you have at least 70 mp, you can do it twice. It sounds OK to me, unless you really care about that.
2. Change energycost in lvlup.c, so you need to do some checks to your characters:

if(name=="fighter")
{
    if(lv>=3) {
      //change freespecial3 to cost only 20 mp,
  } else {
      //change freespecial3 to cost 50 mp
  }
}else if (name=="wizard")
{
    //blahblah...
}


3. Recirect animation in freespecial3

anim freespecial3
@script
if(frame==0)
{
    if(lv<3)
    {
        //change to follow3 or similar animation
        //add mp back if you want or do nothing if you don't care
    }
}
@end_script




Personally I prefer the 3rd solution because I'm lazy, you can make a simple function and @cmd it easily.

The second solution is what I called "perfect" solution, if you don't care about the long script logic.
 
excuse me utunnels, i have another question.
can i do something like this?

Code:
anim freespecial3
@script
if(frame==0)
{
     if(lv<3)
    {
         //mpcost 50
     }    
     else if(lv>3)
    {
         //mpcost 20
     }
}
@end_script

i think it could be the more simple and at the same time effective solution.


something like this maybe?

Code:
anim freespecial3
	energycost 20
	mponly  1
	shadowcoords 218 198
	loop	0
	 offset     225 198
	bbox	0 0 0 0
@script
		
		if(lv<3){
			void self = getlocalvar("self");		
			changeentityproperty(self, "energycost", 50)
		}

you think this could work?
 
No, it won't work.
Because the script only works when the animation is actually played.
 
ok then, so if i want to add this code in the lvlup.c like you said yesterday:
void main()
if(name=="fighter")
{
if(lv>=3){
changeentityproperty(vSelf, "animation", openborconstant("ANI_FREESPECIAL2", "energycost", 20)
}
else {
changeentityproperty(vSelf, "animation", openborconstant("ANI_FREESPECIAL2", "energycost", 50)
}
}
else if (name=="fighter")
{
if(lv>=6){
changeentityproperty(vSelf, "animation", openborconstant("ANI_FREESPECIAL3", "energycost", 20)
}
else {
changeentityproperty(vSelf, "animation", openborconstant("ANI_FREESPECIAL3", "energycost", 80)
}
}
else if (name=="fighter")
{
if(lv>=10){
changeentityproperty(vSelf, "animation", openborconstant("ANI_FREESPECIAL3", "energycost", 20)
}
else {
changeentityproperty(vSelf, "animation", openborconstant("ANI_FREESPECIAL3", "energycost", 120)
}
}

think it could work? i ask you before testing by myself because i'm afraid of make some mess... you know, that backup thing we talked yesterday...  ;)


also the third option is fashinating:
anim freespecial3
@script
if(frame==0)
{
    if(lv<3)
    {
        //change to follow3 or similar animation
        //add mp back if you want or do nothing if you don't care
    }
}
@end_script

but here i've no idea to how write the script in order to make it change animation. :-\

maybe something like this?:
if(lv<3){
changeAni("ANI_FOLLOW3");
 
Utunnels, i'm trying to work on another solution.

this is the code:

Code:
anim freespecial3
#	cancel		{start frame} 	{end frame} {didhit?} 	{sequence of inputs} 	{freespecial#}
	cancel 		2 				999 		0 			f f a 					freespecial2
	cancel 		2 				999 		0 			d u a 					freespecial4
#	energycost 50
#	mponly  1
	jugglecost	99
	shadowcoords 218 198
	load		bomb
	custknife	bomb
	throwframe	2
	loop	0
	offset     225 198
	bbox	0 0 0 0
	sound   data/sounds/att01.wav
	
@script
      int iHP=0;
      int i;
      void ip;
      int rng;
      void self = getlocalvar("self");
      int mp;
      int castx;
		if(frame==0)
		{
        performattack(self, openborconstant ("ANI_ATTACK1"));
		}
		
		else if(frame==1){
        mp = getentityproperty(self, "mp");
        changeentityproperty(self, "mp", mp-20);
		}

@end_script

	delay	8
	frame	data/chars/fighter/frsp101.gif
	delay	2
	frame	data/chars/fighter/frsp102.gif
	delay	120
	sound   data/sounds/slash01.wav
	frame	data/chars/fighter/a112.gif
and this way it works that when the player perform the freespecial3, it automatically change to attack1. no errors until now.

now, i've tried to make something similiar to your code, like this:
Code:
anim freespecial3
#	cancel		{start frame} 	{end frame} {didhit?} 	{sequence of inputs} 	{freespecial#}
	cancel 		2 				999 		0 			f f a 					freespecial2
	cancel 		2 				999 		0 			d u a 					freespecial4
#	energycost 50
#	mponly  1
	jugglecost	99
	shadowcoords 218 198
	load		bomb
	custknife	bomb
	throwframe	2
	loop	0
	offset     225 198
	bbox	0 0 0 0
	sound   data/sounds/att01.wav
	
@script
      int iHP=0;
      int i;
      void ip;
      int rng;
      void self = getlocalvar("self");
      int mp;
      int castx;
		if(frame==0) && (score<6000)
		{
        performattack(self, openborconstant ("ANI_ATTACK1"));
		}
		
		else if(frame==1)
		{
        mp = getentityproperty(self, "mp");
        changeentityproperty(self, "mp", mp-20);
		}

@end_script

	delay	8
	frame	data/chars/fighter/frsp101.gif
	delay	2
	frame	data/chars/fighter/frsp102.gif
	delay	120
	sound   data/sounds/slash01.wav
	frame	data/chars/fighter/a112.gif
i want that if the player perform the freespecial3 AND his score is below 6000, it change to attack1, otherwise it play the freespecial3 normally, but it says that it can't compile script.  :(

i've tried almost anything, this thing is making me crazy  :o
any clues? or i will stick with the simplier solution and leave it as it is.
 
if(frame==0 && score<6000)

One mistake, try it to see if there are other bugs.
 
nope. i've tried this:
Code:
anim freespecial3
#	cancel		{start frame} 	{end frame} {didhit?} 	{sequence of inputs} 	{freespecial#}
	cancel 		2 				999 		0 			f f a 					freespecial2
	cancel 		2 				999 		0 			d u a 					freespecial4
#	energycost 50
#	mponly  1
	jugglecost	99
	shadowcoords 218 198
	load		bomb
	custknife	bomb
	throwframe	2
	loop	0
	offset     225 198
	bbox	0 0 0 0
	sound   data/sounds/att01.wav
	
@script
      int iHP=0;
      int i;
      void ip;
      int rng;
      void self = getlocalvar("self");
      int mp;
      int castx;
		if(frame==0 && score<6000)
		{
        performattack(self, openborconstant ("ANI_ATTACK1"));
		}
		
		else if(frame==1)
		{
        mp = getentityproperty(self, "mp");
        changeentityproperty(self, "mp", mp-20);
		}

@end_script

	delay	8
	frame	data/chars/fighter/frsp101.gif
	delay	2
	frame	data/chars/fighter/frsp102.gif
	delay	120
	sound   data/sounds/slash01.wav
	frame	data/chars/fighter/a112.gif

and the game crash.

this is the log:

Code:
Script compile error in 'animationscript': score line 79, column 23

********** An Error Occurred **********
*            Shutting Down            *

Can't compile script!
Total Ram: 4143374336 Bytes
 Free Ram: 1481838592 Bytes
 Used Ram: 15130624 Bytes

Release level data...........	Done!
Release graphics data........	Done!
Release game data............


Release game data............	Done!
Release timer................	Done!
Release input hardware.......	Done!
Release sound system.........	Done!
Release FileCaching System...	Done!

**************** Done *****************

Can't compile script!
 
Because there's no score. You need to get score from player property first.
 
Back
Top Bottom