|
|
Flying dragon move backward
#455167
10/12/15 04:13
10/12/15 04:13
|
Joined: Jun 2010
Posts: 590 California
Ruben
OP
User
|
OP
User
Joined: Jun 2010
Posts: 590
California
|
Right now I have it in my program to where if the player moves a certain distance toward a flying dragon, the flying dragon will face the player and start moving (flying) toward the player, until the player is a certain distance away where the flying dragon's fixed animated fireball attack will make contact with the player. Once the player reaches this certain distance from the flying dragon, the flying dragon will stop moving, start hovering stationary in the air, and start breathing out fireballs toward the player. If the player tries to move away from the flying dragon, getting out of the certain distance needed for the flying dragon's fireballs to make contact with the player, the flying dragon will stop shooting fireballs at the player, and will start chasing the player using c_move() function. If the flying dragon catches up to the player and gets within that certain distance again, the flying dragon stops chasing, and starts shooting fireballs at the player while hovering stationary in the air, just like last time. Now lets suppose that the player decides to run underneath the flying dragon, rather than away from the flying dragon. If this happens, I would like to make it so that the flying dragon starts to move back in reverse, until the player gets within that certain distance again where the flying dragon's fireballs will make contact with the player. I am trying to figure out how to make the flying dragon do a reverse c_move() away from the player running underneath it. Does anyone know how this can be done? I tried to place a negative sign in different locations within the c_move() instruction, but it is not working. Here is my code so far:
...
action dragon_action()
{
...
my.STATE = 1;
while(1)
{
...
if(my.STATE == 1)
{
...
c_scan(my.x,my.pan,vector(360,0,750),SCAN_ENTS |
SCAN_FLAG2 | IGNORE_ME); // Check to see if
// dragon spots
// player.
if (you) // player detected?
{
my.STATE = 2;
}
}
if(my.STATE == 2)
{
vec_set(temp.x, player.x);
vec_sub(temp.x, my.x);
vec_to_angle(my.pan, temp); // rotate the dragon
// towards the player
c_move(my, vector(100 * time_step, 0, 0), nullvector,
GLIDE); // Dragon chase player
ent_animate(my, "run", anim_percentage, ANM_CYCLE);
anim_percentage += 1 * time_step; // Dragon's chase
// animation
c_scan(my.x,my.pan,vector(360,0,680),SCAN_ENTS |
SCAN_FLAG2 | IGNORE_ME); // Check to see if
// dragon gets
// within firing
// range of player.
if(you) // Player within firing range of dragon?
{
c_move(my, nullvector, nullvector, NULL);
// Dragon stops chasing player
my.ANIMATION += 1.5*time_step;
ent_animate(me,"attack",my.ANIMATION,ANM_CYCLE);
// Dragon does fire breathing
// animation.
dragon_ctrace(); // Does dragon's fireball make
// contact with player? If so,
// player's health reduces.
...
c_scan(my.x,my.pan,vector(360,0,400),SCAN_ENTS |
SCAN_FLAG2 | IGNORE_ME);
// Is player moving too far underneath
// the dragon, getting out of the
// dragon's fireball line of sight?
if(you) // Player too far underneath flying dragon?
{
c_move(my, vector(-8 * time_step, 0, 0),
nullvector, GLIDE);
// Dragon moves backward to get
// player back in its fireball
// line of sight, but this
// c_move() code is not working
// in making this happen.
}
}
}
...
wait(1);
}
}
...
Does anyone know how to reverse c_move() the dragon? It seems like it would be as simple as making the value of the c_move() instruction negative, the exact opposite of the positive c_move() instruction that makes the dragon move forward and chase the player. Anyone know what I am doing wrong in making this happen?
Last edited by Ruben; 10/12/15 04:23.
|
|
|
Re: Flying dragon move backward
[Re: Ruben]
#455170
10/12/15 07:50
10/12/15 07:50
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
c_move example code in the manual :
// move the player using the [W] and [S] keys
var dist_ahead = 5*(key_w-key_s)*time_step;
dist_ahead = sign(dist_ahead)*(abs(dist_ahead) + 0.5*dist_down); // adapt the speed on slopes
c_move(me,vector(dist_ahead,0,0),vector(0,0,-dist_down),IGNORE_PASSABLE | GLIDE); // move the player
check to see if your code enter's this section first, like
if(you) // Player too far underneath flying dragon?
{
printf("ah huh,yap , i am here");
c_move(my, vector(-8 * time_step, 0, 0),
nullvector, GLIDE);
// Dragon moves backward to get
// player back in its fireball
// line of sight, but this
// c_move() code is not working
// in making this happen.
}
Compulsive compiler
|
|
|
Re: Flying dragon move backward
[Re: Wjbender]
#455172
10/12/15 08:14
10/12/15 08:14
|
Joined: Jun 2010
Posts: 590 California
Ruben
OP
User
|
OP
User
Joined: Jun 2010
Posts: 590
California
|
I placed a beep() in place of the printf() statement you mentioned, and yes, it is beeping like crazy, but the dragon is not reversing movement. It is just hovering stationary in the air.
Last edited by Ruben; 10/12/15 08:15.
|
|
|
Re: Flying dragon move backward
[Re: Ruben]
#455175
10/12/15 11:36
10/12/15 11:36
|
Joined: Jul 2001
Posts: 4,801 netherlands
Realspawn

Expert
|

Expert
Joined: Jul 2001
Posts: 4,801
netherlands
|
perhaps placing a certain distance between the dragon and the player pointer that allways have to be the same so it flies with player and player can never walk go past it or in this case keep turning to the player. It uses no reverse it keeps the dragon directed at the player  it still can shoot fireballs while its flying
#define idle 1
#define following 2
#define dead 3
#define status skill1
action my_enemy() // attach this action to your enemies
{
while (!hero) {wait (1);}
var idle_percentage = 0;
var run_percentage = 0;
VECTOR temp;
set (my, POLYGON); // use accurate collision detection
my.status = idle; // that's the same thing with my.skill1 = 1; (really!)
vec_set (temp.x, my.x); // trace 10,000 quants below the player
temp.z -= 10000;
my.z -= c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 20; // play with 20
while (my.status != dead) // this loop will run for as long as my.skill1 isn't equal to 3
{
vec_set (temp.x, my.x); // trace 10,000 quants below the player
temp.z -= 10000;
temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 20; // play with 20
if (my.status == idle) // hanging around?
{
ent_animate(my, "stand", idle_percentage, ANM_CYCLE); // play the "stand" aka idle animation
idle_percentage += 3 * time_step; // "3" controls the animation speed
if (vec_dist (hero.x, my.x) < 1000) // the player has come too close?
{
// scanned in the direction of the pan angle and detected the player?
if ((c_scan(my.x, my.pan, vector(120, 60, 1000), IGNORE_ME) > 0) && (you == hero))
{
my.status = following; // then attack the player even if it hasn't fired at the enemy yet
}
}
}
if (my.status == following) // shooting at the player?
{
vec_set(temp, hero.x);
vec_sub(temp,my.x);
vec_to_angle(my.pan, temp); // turn the enemy towards the player
if (vec_dist (hero.x, my.x) > 100) // the distance between player and enemy is bigger than 100 quants?
{
c_move (my, vector(10 * time_step, 0, temp.z), nullvector, GLIDE); // move towards the player
ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation
run_percentage += 6 * time_step; // "6" controls the animation speed, using normal animation
}
if (vec_dist (hero.x, my.x) < 90) // the distance between player and enemy is smaller than 90 quants?
{
c_move (my, vector(-10 * time_step, 0, temp.z), nullvector, GLIDE); // move away from the player
ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation
run_percentage -= 6 * time_step; // "6" controls the animation speed, using a reversed animation
}
if (vec_dist (hero.x, my.x) > 500) // the player has moved far away from the enemy?
{
my.status = idle; // then switch to "idle"
}
}
wait (1);
}
set (my, PASSABLE); // allow the player to pass through the corpse now
}
here is a clip that shows it in action you can make it use any animation or function you want. https://youtu.be/eQzcIWnrJs0
Last edited by Realspawn; 10/12/15 11:52.
|
|
|
Re: Flying dragon move backward
[Re: Ruben]
#455177
10/12/15 12:15
10/12/15 12:15
|
Joined: Dec 2011
Posts: 1,823 Netherlands
Reconnoiter
Serious User
|
Serious User
Joined: Dec 2011
Posts: 1,823
Netherlands
|
I placed a beep() in place of the printf() statement you mentioned, and yes, it is beeping like crazy, but the dragon is not reversing movement. It is just hovering stationary in the air. , so if it beeps than the reverse c_move is triggered. But perhaps its effect is too small? Try a larger number just for debugging purposes. Also check if the other normal c_move (/that lets the dragon move forward) is still triggered. Perhaps both c_move's are triggered so the dragon moves backwards and forwards simultaneously.
|
|
|
Re: Flying dragon move backward
[Re: Reconnoiter]
#455194
10/12/15 17:58
10/12/15 17:58
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
thats possible . I would recommend you also add a debug_var for my.state , to see if your states remain valid during the time , it mght be that the states are flipping around fast ... and i am wondering now if the you remains valid ,where you might have to set it empty ?
if(you) // Player within firing range of dragon?
{
c_move(my, nullvector, nullvector, NULL);
// Dragon stops chasing player
my.ANIMATION += 1.5*time_step;
ent_animate(me,"attack",my.ANIMATION,ANM_CYCLE);
// Dragon does fire breathing
// animation.
dragon_ctrace(); // Does dragon's fireball make
// contact with player? If so,
// player's health reduces.
...
you=NULL;/////////////////////?????????????????
c_scan(my.x,my.pan,vector(360,0,400),SCAN_ENTS |
SCAN_FLAG2 | IGNORE_ME);
// Is player moving too far underneath
// the dragon, getting out of the
// dragon's fireball line of sight?
if(you) // Player too far underneath flying dragon?
{
c_move(my, vector(-8 * time_step, 0, 0),
nullvector, GLIDE);
// Dragon moves backward to get
// player back in its fireball
// line of sight, but this
// c_move() code is not working
// in making this happen.
}
}
}
because in the manual it states :To prevent that a scanning entity triggers itself, set IGNORE_ME. To ignore a certain entity, set you to the entity pointer. but , i dont know if the you pointer changes during the same frame and if it changes during the same frame to empty again or what....
Compulsive compiler
|
|
|
Re: Flying dragon move backward
[Re: Wjbender]
#455197
10/13/15 00:18
10/13/15 00:18
|
Malice
Unregistered
|
Malice
Unregistered
|
Hello, I this case I would test without the beep(). Beep() has a built-in wait. When you here beeping like crazy you are also returning and waiting like crazy. For this case I use set(my,LIGHT); my.red=0; but not a beep(); The beep(); wait will cause if(you) to fail as 'you' will be possibly reset to another entity. Also if(you) is poor. Try if(you == player) or whatever pointer. Also you use many c_scans to do the work that one can do. At any one time every place you have if(you) and c_scan than the IF's are all true. You are in fact running all your c_moves as 'you' will all most always have some value and you IF is just a binary of does 'you' have any value or no value. Even if the scan fails to detect the player 'you' will have a value if(you == player) on the other hand! Use one c_scan and one c_move and use id or scan_codes. Also again this can use the event system If the my entity has ENABLE_DETECT set, it's event function is triggered once for every detected entity. During the event, event_type is set to EVENT_DETECT and you is set to the detected entity. This way all detected entities can be enumerated. i dont know if the you pointer changes during the same frame and if it changes during the same frame to empty again or what.... YOU - should almost always have a value c_move c_scan and many others are always setting it. So do not IF it Boolean if(you) will be true but YOU may not be the player. Again if(you == player) YOU and ME almost always have value, they are meant for comparisons. Even in checking for a ENT not a BLOCK do not if(!you) ... Instead if(you != NULL) Even more YOU and ME are set by every ent , the player my set YOU in it's c_move, the dragons c_scan detects nothing but if(you) is TRUE because the player gave it value. YOU is not exclusive to the running function.
Last edited by Malice; 10/13/15 00:20.
|
|
|
Re: Flying dragon move backward
[Re: ]
#455198
10/13/15 00:35
10/13/15 00:35
|
Malice
Unregistered
|
Malice
Unregistered
|
In state==1 you are going to drop straight to state ==2 because if(you) will almost always be true. Again here ALL c_moves will run because all if(you) are true. If c_scan fails it does NOT set 'you = NULL', so you still holds it's last value. Also lets talk about the states? Charging the player should be one, hovering should be one, backing away should be one. my.state = CHARGING; my.state = HOVORING; my.state = BACKING_UP; Regardless of the results of the c_scans every line of the below code should execute.
c_move(my, vector(100 * time_step, 0, 0), nullvector,
GLIDE); // Dragon chase player
ent_animate(my, "run", anim_percentage, ANM_CYCLE);
anim_percentage += 1 * time_step; // Dragon's chase
// animation
c_scan(my.x,my.pan,vector(360,0,680),SCAN_ENTS |
SCAN_FLAG2 | IGNORE_ME); // Check to see if
// dragon gets
// within firing
// range of player.
if(you) // Player within firing range of dragon?
{
c_move(my, nullvector, nullvector, NULL);
// Dragon stops chasing player
my.ANIMATION += 1.5*time_step;
ent_animate(me,"attack",my.ANIMATION,ANM_CYCLE);
// Dragon does fire breathing
// animation.
dragon_ctrace(); // Does dragon's fireball make
// contact with player? If so,
// player's health reduces.
...
c_scan(my.x,my.pan,vector(360,0,400),SCAN_ENTS |
SCAN_FLAG2 | IGNORE_ME);
// Is player moving too far underneath
// the dragon, getting out of the
// dragon's fireball line of sight?
if(you) // Player too far underneath flying dragon?
{
c_move(my, vector(-8 * time_step, 0, 0),
nullvector, GLIDE);
// Dragon moves backward to get
// player back in its fireball
// line of sight, but this
// c_move() code is not working
// in making this happen.
}
}
}
From manual on c_scan you -- Pointer to the closest detected entity. "" Mal - otherwise holds the value of the last pointer entered into the YOU pointer ""
Last edited by Malice; 10/13/15 01:36.
|
|
|
Re: Flying dragon move backward
[Re: ]
#455199
10/13/15 01:27
10/13/15 01:27
|
Malice
Unregistered
|
Malice
Unregistered
|
#define STATE skill1
#define ANM_PERCENT skill2
#define ANIMATION skill3
#define ST_WAITING 0
#define ST_CHASING 1
#define ST_HOVERING 2
#define ST_BACK_UP 3
#define ANM_SPEED_RUN 1
#define ANM_SPEED_ATTACK 1.5
action dragon()
{
STRING* amn_str = "";
// scan VEC
my.skill10 = 360;
my.skill11 = 0;
my.skill12 = 700;
// MOV_VEC
vec_set(my.skill80,nullvector); // using skill80-82
// Scan results
my.skill90 = 0;
//////////////////////////////////
my.STATE = ST_WAITING;
.../// stuff
while(1)
{
// do all scans at one place
my.skill90 = c_scan(my.x,my.pan,my.skill10, SCAN_ENTS | SCAN_FLAG2 | IGNORE_ME);
if(my.skill90 && you == player)
{
if(my.STATE == ST_WAITING)
my.STATE= ST_CHASING;
if(my.STATE == ST_CHASING)
my.STATE = HOVERING;
if(my.STATE == ST_HOVERING)
my.STATE = ST_BACK_UP;
}
else
{
if(my.STATE == ST_BACK_UP)
my.STATE = ST_CHASE;
}
if(my.STATE == ST_WAITING)
{
my.skill10 =360;
my.skill11 = 0;
my.skill12 = 750;
vec_set(my.skill80,nullvector);
str_cpy(anm_str,"idle");
my.ANM_PERCENT = ANM_SPEED_RUN;
}
if(my.STATE == ST_CHASING)
{
vec_set(temp.x, player.x);
vec_sub(temp.x, my.x);
vec_to_angle(my.pan, temp); // rotate the dragon
// towards the player
vec_set(my.skill10, vector(360,0,680));
vec_set(my.skill80,vector(100,0,0));
str_cpy(anm_str,"run");
my.ANM_PERCENT = ANM_SPEED_RUN;
}
if(my.STATE == ST_HOVERING)
{
vec_set(temp.x, player.x);
vec_sub(temp.x, my.x);
vec_to_angle(my.pan, temp); // rotate the dragon
// towards the player
vec_set(my.skill10, vector(360,0,400));
vec_set(my.skill80,nullvector);
str_cpy(anm_str,"attack");
my.ANM_PERCENT = ANM_SPEED_ATTACK;
dragon_ctrace(); // Does dragon's fireball make
// contact with player? If so,
// player's health reduces.
}
if(my.STATE == ST_BACK_UP)
{
vec_set(temp.x, player.x);
vec_sub(temp.x, my.x);
vec_to_angle(my.pan, temp); // rotate the dragon
// towards the player
vec_set(my.skill10, vector(360,0,400));
vec_set(my.skill80,vector(-20,0,0));
str_cpy(anm_str,"attack");
my.ANM_PERCENT = ANM_SPEED_ATTACK;
}
/// STATES FINISHED --- SHOULD USE A SWITCH NOT FALLING "IF's"
// Do movement
vec_scale(my.skill80,time_step);
c_move(my,my.skill80,nullvector, GLIDE);
// DO ANMATION
ent_animate(my, anm_str,my.ANIMATION,ANM_CYCLE);
my.ANIMATION+=my.ANM_PERCENT*time_step;
my.ANIMATION%=100;
wait(1);
}
It might not be right but it's right-er!
|
|
|
Re: Flying dragon move backward
[Re: ]
#455201
10/13/15 08:16
10/13/15 08:16
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
yeah you could probably get away with using less scans .. i suggest you always check your scans before you check the you-pointer as a general piece of advice , because in the manual it states :you Is preserved in functions during wait().
var result=c_trace(....);
if(result>0)//object found
{
//now check the you pointer
}
now on-wards ,also you in your 2nd state you have this pieces of code i think are clashing here you have code that stops the dragon moving , why ? this tells me your trying to stop another movement ,which means theres another scan that happened succesfull and its code is moving the dragon and your trying to forcefully stop it here with this :
c_move(my, nullvector, nullvector, NULL);
// Dragon stops chasing player
which i think clashes with this
if(you) // Player too far underneath flying dragon?
{
c_move(my, vector(-8 * time_step, 0, 0),
because , your dragon is still within firing range while the player is underneath the dragon . to resolve this i think you need two distance checks i suppose this example would check in radius , but ignore the height difference , like a flat disk radius check
//here is 3 use-able conditions for states
//check if the player is under the dragon
if (vec_dist(player.x,vector(dragon.x,dragon.y,player.z)) < under_dragon_radius)
{
//player is under dragon
}
//check if the player is not under the dragon but within shooting range
if (vec_dist(player.x,vector(dragon.x,dragon.y,player.z)) > under_dragon_radius)
{
//player is not under dragon
if(vec_dist(player.x,vector(dragon.x,dragon.y,player.z)) < dragon_shooting_radius)
{
//the player is not under the dragon and is within shooting range
}
}
//check if the player is not under the dragon and out of shooting range
if (vec_dist(player.x,vector(dragon.x,dragon.y,player.z)) > dragon_shooting_radius)
{
//player is not under dragon and not within shooting range
}
if you want to include height checking , like a 3d sphere radius check ,then include the height difference in the checks
if (vec_dist(player.x,dragon.x))...
//instead of
if (vec_dist(player.x,vector(dragon.x,dragon.y,player.z))...
example 1 on top of image ,example 2 at bottom of image (side viewed)
Last edited by Wjbender; 10/13/15 08:45.
Compulsive compiler
|
|
|
Moderated by mk_1, Perro, rayp, Realspawn, Rei_Ayanami, rvL_eXile, Spirit, Superku, Tobias, TSG_Torsten, VeT
|