VECTOR move_vec;
VECTOR friction_vec;
VECTOR min_vec;
function target_circle();
function command_arrow();
function lockon_circle();
function control_circle();
var camera_lockon_interpolate = 0.5; //when set to lockon camera this is set to 0.1 to allow camera to start moving with slower acceleration
//skill1:combatant_behavior_id, determines what type of model is being used, a wolf, a warrior, for animation sets etc
//skill2:movement_speed, speed at which combatant moves
//skill4:statistic_ID, id of stats which determines health etc
//skill6:leader_id, id of leader
//skill7:combatant_model_ID, ID of the actual animated model to attach to the combatant's collision hull, beast, warrior etc
//skill8:ent_formation_id, initial state of formation of entity leader
function combatant_scan_event() { //combatants finding target to attack
if (event_type == EVENT_DETECT) {
//if we have scanned a friendly
if ((my.entity_type == type_combatant_enemy && you.entity_type == type_combatant_enemy) || (my.entity_type == type_combatant_friendly && you.entity_type == type_combatant_friendly)) {
if (my.entity_type == type_combatant_friendly && attracting_ent) {
if (my.leading_ent == 0 && attracting_ent == you && my.formation_amount == 0 && my.formation_distance == 0) {
my.ai_command_state = 0;
my.leading_ent = handle(attracting_ent);
leader_ent = attracting_ent;
leader_ent.formation_amount += 1;
my.formation_follower_ID = leader_ent.formation_amount + 1; //store our id in formation
my.formation_distance = 60 + random(50);
}
}
if (my.entity_type == type_combatant_enemy && you.leader > 0) {
leader_ent = ptr_for_handle(my.leading_ent);
if (leader_ent) {
if (you.leader < leader_ent.leader) { //another leader is stronger follow that one
leader_ent.formation_amount -= 1;
you.formation_amount += 1;
my.leading_ent = handle(you);
}
} else {
my.leading_ent = handle(you);
leader_ent = you;
}
if (leader_ent && ptr_for_handle(my.friendly_ent) != you && my.formation_distance == 0) {
// my.formation_distance = leader_ent.formation_amount * 60;
leader_ent.formation_amount += 1;
my.formation_follower_ID = leader_ent.formation_amount + 1; //store our id in formation
my.formation_distance = 60 + random(50);
}
}
if (vec_dist(my.x,you.x) < friendly_scan_target_distance) {
friend_ent = ptr_for_handle(my.friendly_ent);
if (friend_ent) {
//is the new target closer than the current one
if (vec_dist(you.x,my.x) < vec_dist(friend_ent.x,my.x)) {
my.friendly_ent = handle(you);
}
} else {
my.friendly_ent = handle(you);
}
}
if (my.formation_distance != 0) { return; }
}
/* if (selected_ent) {
if (player == my && selected_ent.entity_type == type_combatant_enemy) {
my.targeted_ent = handle(selected_ent);
return;
}
}*/
//if we have scanned our enemy
if ((my.entity_type == type_combatant_enemy && you.entity_type == type_combatant_friendly) || (my.entity_type == type_combatant_friendly && you.entity_type == type_combatant_enemy)) {
result = scan_target_distance;
result2 = defensive_target_distance;
if (player == my) { result = 1000; result2 = 1000; }
if ((vec_dist(my.x,you.x) < result && (my.ai_aggression_state == ai_aggressive || player == my)) || (my.ai_aggression_state == ai_defensive && vec_dist(my.x,you.x) < result2)) {
temp_ent = ptr_for_handle(my.targeted_ent);
if (temp_ent == you) { return; }
if (temp_ent) {
//is the new target closer than the current one
temp_ent2 = ptr_for_handle(you.targeted_ent); //the enemy we've found, the combatant they are targeting
temp_ent3 = ptr_for_handle(temp_ent.targeted_ent); //the enemy we're targeting, the combatant they are targeting
//if the scanned enemy is more of a threat than the other
if (temp_ent2 == my && temp_ent3 != my) {
my.targeted_ent = handle(you);
}
//if both enemies are a threat, or neither are a threat, attack the cloest one
if ((temp_ent2 == my && temp_ent3 == my && vec_dist(temp_ent.x,my.x) > 100) || (temp_ent2 != my && temp_ent3 != my)) {
if (vec_dist(you.x,my.x) < vec_dist(temp_ent.x,my.x)) {
my.targeted_ent = handle(you);
}
}
} else {
my.targeted_ent = handle(you);
}
}
}
}
if (event_type == EVENT_ENTITY) {
if (you != player) { // && you.leader == 0
if (you.entity_type == my.entity_type) {
vec_diff(you.push_x,you.x,my.x);
vec_normalize(you.push_x,you.store_movement_speed * 4 * time_step);
}
if (you.entity_type == type_container_destroy) { //physics object
vec_diff(you.push_x,you.x,my.x);
}
}
}
}
function handle_gravity() {
if (npc_gravity_state == 1) {
//use_box
result = c_trace(my.x,vector(my.x,my.y,my.z - 4000),USE_BOX|IGNORE_ME|IGNORE_PASSABLE);
} else {
if (player == my) {
//use_box
result = c_trace(my.x,vector(my.x,my.y,my.z - 4000),USE_BOX|IGNORE_ME|IGNORE_PASSABLE);
} else {
//ray trace
result = c_trace(vector(my.x,my.y,my.z + my.min_z),vector(my.x,my.y,my.z - 4000),IGNORE_ME|IGNORE_PASSABLE);
result = c_trace(vector(my.x,my.y,my.z + my.min_z),vector(my.x,my.y,my.z - 4000),IGNORE_ME|IGNORE_PASSABLE);
}
}
my.z_dist = result - 3; //move the character 3 quants above ground to avoid hull creating collision with ground
vec_to_angle(temp7.pan,normal);
my.ground_angle = temp7.pan;
my.ground_tilt = normal.z;
if (my.z_dist < 3) {
//if character is within 3 quants to ground
my.force_z = -1 * my.z_dist;
} else {
//if character is above ground
my.force_z -= 4 * time_step;
my.force_z = maxv(-30,my.force_z);
}
//calculate force to move player downwards
my.velocity_z += (time_step * my.force_z) - (minv(time_step*0.7,1) * my.velocity_z);
my.move_z = my.velocity_z * time_step;
//if character has fallen below the floor, immediately move it upwards to floor height
if (my.z_dist < 0) { my.move_z = -my.z_dist; my.velocity_z = 0; my.force_z = 0; }
}
function handle_target() {
leader_ent = ptr_for_handle(my.leading_ent);
//find nearest target to player
result5 = combatant_c_scan_distance;
// if (player == my) { result5 = player_scan_target_distance; }
target_ent = ptr_for_handle(my.targeted_ent);
c_scan(my.x,my.pan,vector(360,180,result5),SCAN_ENTS | SCAN_LIMIT | IGNORE_ME);
if (target_ent) {
//if our target has moved out of range
result = result5 + 20;
//if we are locking on twice the distance to remove target
if (player == my && player_targeting_mode == 0) {
if (selected_ent) {
if (selected_ent.entity_type == type_combatant_enemy) {
target_ent = selected_ent;
}
}
// result = result5 * 20;
// if (!selected_ent && !target_ent) {
// result = result5 + 20;
// }
}
if (vec_dist(my.x,target_ent.x) > result || target_ent.state_machine == state_death || target_ent.state_machine == state_remove) {
target_ent = NULL;
my.targeted_ent = 0;
}
}
//looking at friendly units
temp_ent = ptr_for_handle(my.friendly_ent);
if (temp_ent) {
// if (leader_ent) {
if (!leader_ent && my.formation_distance != 0) { //if we aren't following leader and we have been, reset formation distance
my.formation_distance = 0;
// my.formation_state = 0;
// my.leading_ent = 0;
// my.formation_follower_ID = 0;
// my.formation_amount = 0;
// my.formation_state = 0;
}
// }
result = friendly_scan_target_distance + 20;
if (vec_dist(my.x,temp_ent.x) > result || temp_ent.state_machine == state_death || temp_ent.state_machine == state_remove) {
my.friendly_ent = 0;
}
}
}
function handle_player_input() {
//calculate movement based on player input
my.velocity_x = 0;
my.velocity_y = 0;
my.move_x = 0;
my.move_y = 0;
if (camera_movement_mode == camera_freemove_mode) { return; } //remove player input while in camera freemove mode
// my.formation_state = 0;
if (key_p == 0 && p_press == 1) { p_press = 0; }
if (key_p == 1 && p_press == 0) { p_press = 1; freeze_non_player = (freeze_non_player == 0); }
if (key_i == 0 && key_o == 0 && o_press == 1) { o_press = 0; }
if (key_o == 1 && o_press == 0) { o_press = 1; time_factor = minv(time_factor + 0.1,1); }
if (key_i == 1 && o_press == 0) { o_press = 1; time_factor = maxv(time_factor - 0.1,0.1); }
if (key_u == 1) { time_factor = 1; }
if (key_y == 1) { time_factor = 0.1; }
if (my.leader > 0) {
if (my.formation_state == formation_line_back) {
my.formation_angle = camera.pan - 180;
my.formation_x = my.x + fcos(my.formation_angle,-60);
my.formation_y = my.y + fsin(my.formation_angle,-60);
}
if (my.formation_state == formation_front) {
my.formation_angle = camera.pan;
my.formation_x = my.x + fcos(my.formation_angle,100);
my.formation_y = my.y + fsin(my.formation_angle,100);
}
if (my.formation_state == formation_circle) {
my.formation_angle = 0;
my.formation_x = my.x;
my.formation_y = my.y;
}
if (my.formation_state == formation_pincer) {
my.formation_angle = camera.pan;
my.formation_x = my.x + fcos(my.formation_angle,100);
my.formation_y = my.y + fsin(my.formation_angle,100);
}
if (my.formation_state == formation_break) { my.formation_state = 0; }
if (my.state_machine == state_null) {
if (pkey_1 == 1 && k1_press == 0 && my.formation_state == 0) {
k1_press = 1;
my.formation_state = formation_pincer;
my.formation_angle = my.pan;
my.formation_x = my.x;
my.formation_y = my.y;
}
if (pkey_2 == 1 && k2_press == 0 && my.formation_state == 0) {
k2_press = 1;
my.formation_state = formation_front;
my.formation_angle = my.pan;
my.formation_x = my.x;
my.formation_y = my.y;
}
if (pkey_3 == 1 && k3_press == 0 && my.formation_state == 0) {
k3_press = 1;
my.formation_state = formation_circle;
my.formation_angle = 0;
my.formation_x = my.x;
my.formation_y = my.y;
}
if (key_0 == 1) {
my.formation_state = formation_break;
}
if (my.formation_state != 0) {
/* pkey_up = 0;
pkey_down = 0;
pkey_left = 0;
pkey_right = 0;
pkey_action = 0;
pkey_lockon = 0;*/
}
}
}
//move and pan in a direction relative to camera
temp2.pan = -1000;
temp3.pan = 0; //amount to pan camera
if (pkey_up == 1 && pkey_down == 0 && pkey_left == 0 && pkey_right == 0) { temp2.pan = camera.pan; }
if (pkey_down == 1 && pkey_up == 0 && pkey_left == 0 && pkey_right == 0) { temp2.pan = camera.pan + 180; }
if (pkey_left == 1 && pkey_down == 0 && pkey_up == 0 && pkey_right == 0) { temp2.pan = camera.pan + 90; temp3.pan += 5 * time_step; }
if (pkey_right == 1 && pkey_down == 0 && pkey_left == 0 && pkey_up == 0) { temp2.pan = camera.pan - 90; temp3.pan -= 5 * time_step; }
if (pkey_up == 1 && pkey_left == 1 && pkey_right == 0 && pkey_down == 0) { temp2.pan = camera.pan + 45; temp3.pan += 2.5 * time_step; }
if (pkey_up == 1 && pkey_right == 1 && pkey_left == 0 && pkey_down == 0) { temp2.pan = camera.pan - 45; temp3.pan -= 2.5 * time_step; }
if (pkey_down == 1 && pkey_left == 1 && pkey_right == 0 && pkey_up == 0) { temp2.pan = camera.pan + 135; temp3.pan += 6 * time_step; }
if (pkey_down == 1 && pkey_right == 1 && pkey_left == 0 && pkey_up == 0) { temp2.pan = camera.pan - 135; temp3.pan -= 6 * time_step; }
if (my.formation_state == 0) {
camera_pan += temp3.pan;
}
//move player combatant
my.store_movement_speed = my.movement_speed;
if (temp2.pan != -1000) {
if (pkey_shift == 1) { my.store_movement_speed *= 0.6; }
my.rot_pan_to = temp2.pan;
my.velocity_x = fcos(temp2.pan,my.store_movement_speed * time_step);
my.velocity_y = fsin(temp2.pan,my.store_movement_speed * time_step);
} else {
//if we arn't moving don't pan
my.rot_pan_to = my.pan;
}
if (my.formation_state == formation_front) {
my.rot_pan_to = camera.pan;
}
//face the combatant we are targeting
if (target_ent && player_targeting_mode == 1) {
vec_to_angle(temp7.pan,vec_diff(temp7,target_ent.x,my.x));
my.rot_pan_to = temp7.pan;
}
//handle locking onto target
if (target_ent && pkey_lockon == 1 && lockon_press == 0) {
lockon_press = 1;
player_targeting_mode = (player_targeting_mode == 0);
if (player_targeting_mode == 1) {
selected_ent = target_ent;
camera_lockon_interpolate = 0.1;
}
if (player_targeting_mode == 0 && selected_ent) {
if (selected_ent.entity_type == type_combatant_enemy) { selected_ent = NULL; }
}
}
if (target_ent!=NULL && selected_ent!=NULL) {
// && selected_ent.entity_type != target_ent.entity_type
if (player_targeting_mode == 1) { selected_ent = target_ent; } //target closest enemy if in targetting mode
}
if (!target_ent) { player_targeting_mode = 0; } else {
if (vec_dist(my.x,target.x) < 100 && my.formation_state > 0) {
// my.formation_state = formation_break;
}
}
//begin and continue an attack
//begin and continue an attack
if (my.state_machine == state_null && my.attack_delay == 0) {
if (pkey_action == 1 && action_press == 0) {
action_press = 1;
my.state_machine = state_attack;
// animate_ent.blendframe = jump_attack;
}
}
if (my.state_machine == state_null && my.attack_delay == 0 && my.combatant_type == 0) {
if (pkey_action2 == 1 && action2_press == 0) {
if (animate_ent.blendframe == nullframe) {
if (animate_ent.animblend < attack_a || animate_ent.animblend >= 50) {
result2 = 0;
if (target_ent != NULL) {
result5 = vec_dist(my.x,target_ent.x);
if (result5 < 120) { result2 = 1; }
}
action2_press = 1;
my.state_machine = state_attack;
if (result2 == 1) { animate_ent.blendframe = bash_attack; } else {
animate_ent.blendframe = jump_attack;
if (player_targeting_mode == 1) {
if (result5 < 150) { animate_ent.blendframe = jump_attack + 0.4; }
if (result5 < 200) { animate_ent.blendframe = jump_attack + 0.3; }
}
}
}
}
}
}
if (my.state_machine == state_attack) {
if (animate_ent.animblend >= attack_a && animate_ent.animblend < 50) {
if (pkey_action == 1 && action_press == 0) {
action_press = 1;
my.combo_continue = 1;
}
}
}
}
function handle_ai_input() {
//this code determines how the ai behaves
if (my.formation_state != 0 && leader_ent == NULL) {
if (my.formation_state == formation_front) {
my.formation_angle = my.pan;
my.formation_x = my.x + fcos(my.formation_angle,100);
my.formation_y = my.y + fsin(my.formation_angle,100);
}
if (my.formation_state == formation_circle) {
my.formation_angle = 0;
my.formation_x = my.x;
my.formation_y = my.y;
}
if (my.formation_state == formation_pincer) {
my.formation_angle = my.pan;
my.formation_x = my.x + fcos(my.formation_angle,100);
my.formation_y = my.y + fsin(my.formation_angle,100);
}
if (my.formation_state == formation_break) { my.formation_state = 0; }
}
temp5.x = my.velocity_x; temp5.y = my.velocity_y; //store last frame's movement
my.velocity_x = 0;
my.velocity_y = 0;
my.move_x = 0;
my.move_y = 0;
my.store_movement_speed = my.movement_speed;
result5 = 0;
result_local=0;
if (target_ent) {
if (my.formation_state == formation_circle) {
if (leader_ent) {
if (vec_dist(target_ent.x,leader_ent.x) < 400) { //if target is close to centre of circle everyone attacks
result_local = 1;
}
}
if (vec_dist(my.x,target_ent.x) < 100) { //if we are really close to target
result_local = 1;
}
} else {
result_local = 1;
}
}
if (result_local == 1) {
if ((my.ai_command_state == ai_command_guard) || (my.ai_command_state == ai_command_chase && vec_dist(my.x,my.move_to_x) > 100)) {
//move towards commanded position
handle_ai_move_to();
} else {
if (my.ai_command_state == ai_command_chase) { my.ai_command_state = 0; }
handle_ai_attack_target();
}
} else {
if (my.ai_command_state == ai_command_guard || my.ai_command_state == ai_command_chase) {
//move towards commanded position
handle_ai_move_to();
} else {
//move in formation
handle_ai_formation();
}
}
if (my.ai_command_state == 0) {
handle_ai_collision_avoidance();
}
}
function process_state_machines(){
//process movement based on state machine
if (my.state_machine == state_attack) {
if (animate_ent.animblend >= attack_a && animate_ent.animblend < 50) {
if (animate_ent.animblend == bash_attack || animate_ent.blendframe == bash_attack) { handle_attack_collision(); }
my.rot_pan_to = my.pan;
if ((target_ent && player != my) || (player == my && target_ent && player_targeting_mode == 1)) {
vec_to_angle(temp7.pan,vec_diff(temp7,target_ent.x,my.x));
my.rot_pan_to = temp7.pan;
}
my.velocity_x = 0;
my.velocity_y = 0;
result_local = 0;
if (target_ent) {
//don't move towards target if we are too close
if (vec_dist(my.x,target_ent.x) < (my.max_y - my.min_y*2)) { result_local = 1; }
}
if (result_local == 0) {
//move combatant forward at a speed based on it's progress in attacking animation
my.move_x = fcos(minv(animate_ent.animate * 0.9,90),my.animation_movement_speed);
if (my.animation_movement_speed < 0) { //value below 0, use sin instead of cos for controlling movement
my.move_x = fsin(minv(animate_ent.animate * 0.9,90),abs(my.animation_movement_speed));
}
if (my.animation_movement_speed > 1000 && my.animation_movement_speed < 2000) { //value above 1000, move at a steady consistent speed
my.move_x = my.animation_movement_speed - 1000;
}
if (my.animation_movement_speed > 2000 && my.animation_movement_speed < 3000) { //value above 2000, move only during the first 50% of the animation, jump attack etc
my.move_x = fcos(minv((animate_ent.animate * 1.8) - 45,90),my.animation_movement_speed - 2000);
}
my.move_x *= time_step;
// my.animation_z_offset
}
}
}
if (my.state_machine == state_pain) {
//my.original_x is the coordinate of the ENTITY that hit us, when it hit us
my.velocity_x = 0;
my.velocity_y = 0;
if (animate_ent.blendframe == hit_recoil) { //move at max speed while blending
vec_to_angle(temp.x,vec_diff(temp,my.original_x,my.x));
my.rot_pan_to = temp.x;
result = my.animation_movement_speed * time_step;
my.velocity_x = fcos(temp.x,-result);
my.velocity_y = fsin(temp.x,-result);
}
if (animate_ent.animblend >= hit_a && animate_ent.animblend <= hit_recoil) {
// my.rot_pan_to = my.pan;
vec_to_angle(temp.x,vec_diff(temp,my.original_x,my.x));
my.rot_pan_to = temp.x;
result = fcos(minv(animate_ent.animate * 0.9,90),my.animation_movement_speed);
if (my.animation_movement_speed > 1000) { //value above 1000, move at a steady consistent speed
result = my.animation_movement_speed - 1000;
}
result *= time_step;
my.velocity_x = fcos(temp.x,-result);
my.velocity_y = fsin(temp.x,-result);
}
}
}
function process_animation() {
if (my.state_machine == state_attack) {
//if we aren't attacking
if (animate_ent.blendframe == nullframe) {
if (animate_ent.animblend < attack_a || animate_ent.animblend >= 50) {
if (random(1) > 0.5 || my.combatant_type != 0) {
animate_ent.blendframe = attack_a;
} else {
animate_ent.blendframe = attack_d;
}
}
}
return;
}
if (my.state_machine == state_pain) {
//if we aren't in a pain animation
if (my.health <= 0) {
my.state_machine = state_death;
temp_panel = ptr_for_handle(my.health_panel);
pan_remove(temp_panel);
if (selected_ent == my) { selected_ent = NULL; }
} else {
if (animate_ent.blendframe == nullframe) {
if (animate_ent.animblend < hit_a || animate_ent.animblend > hit_recoil) {
determine_pain_animation(); //function is found in c_animation.wdl
}
}
return;
}
}
if (my.state_machine == state_death) {
if (animate_ent.blendframe == nullframe) {
if (animate_ent.animblend < die_a || animate_ent.animblend > die_d) {
determine_death_animation(); //function is found in c_animation.wdl
}
}
return;
}
result_local = 0;
if (target_ent && player != my) {
if (vec_dist(my.x,target_ent.x) > scan_target_distance * 0.5) { result_local = 1; }
}
// && my.formation_state == 0
if (is(my,no_strafe)) { result_local = 1; } //don't strafe
if ((target_ent == NULL) || (player == my && player_targeting_mode == 0 && my.formation_state == 0) || (result_local == 1)) { //we are not targeting another combatant
if (animate_ent.blendframe == nullframe) { //combatant isn't blending animations
if (my.velocity_x != 0 || my.velocity_y != 0 || my.move_x != 0 || my.move_y != 0) {
if (my.store_movement_speed < my.movement_speed * 0.7) {
if (animate_ent.animblend != walk) { animate_ent.blendframe = walk; }
} else {
if (animate_ent.animblend != run) { animate_ent.blendframe = run; }
}
} else {
if (animate_ent.animblend != stand) { animate_ent.blendframe = stand; }
}
}
} else {
if (animate_ent.blendframe == nullframe) { //combatant isn't blending animations
if (my.velocity_x != 0 || my.velocity_y != 0 || my.move_x != 0 || my.move_y != 0) {
//strafe based on movement direction
vec_to_angle(temp7.pan,my.velocity_x);
result_local = ang(temp7.pan - my.pan);
if (abs(result_local) > 120 && animate_ent.animblend != run) { animate_ent.blendframe = run; }
if (result_local >= 50 && result_local <= 120 && animate_ent.animblend != strafe_left) {
if ((animate_ent.animblend == strafe_forward && result_local > 60) || (animate_ent.animblend == strafe_back && result_local <= 110)) {
animate_ent.blendframe = strafe_left;
} else {
animate_ent.blendframe = strafe_left;
}
}
if (result_local <= -50 && result_local >= -120 && animate_ent.animblend != strafe_right) {
if ((animate_ent.animblend == strafe_forward && result_local < -60) || (animate_ent.animblend == strafe_back && result_local >= -110)) {
animate_ent.blendframe = strafe_right;
} else {
animate_ent.blendframe = strafe_right;
}
}
if (abs(result_local) < 50 && animate_ent.animblend != run) { animate_ent.blendframe = run; }
} else {
if (animate_ent.animblend != stand) { animate_ent.blendframe = stand; }
}
}
}
}
function process_movement() {
if (my.ground_tilt < 0.2 && player == my && my.z_dist < 10) {
my.move_x = 0;
my.move_y = 0;
result5 = 1.2;
if (my.ground_tilt < 0.1) { result5 *= 2; }
my.velocity_x = fcos(my.ground_angle,my.movement_speed * time_step * result5);
my.velocity_y = fsin(my.ground_angle,my.movement_speed * time_step * result5);
}
result2 = my.movement_speed;
accelerate(my.force_x,my.velocity_x*0.85,0.85);
accelerate(my.force_y,my.velocity_y*0.85,0.85);
if (my.state_machine != state_pain) {
if ((my.formation_state == 0 && player != my) || (player == my && player_targeting_mode == 0 && my.formation_state == 0)) {
if ((abs(my.force_x) > 1 || abs(my.force_y) > 1) && (target_ent == NULL)) {
vec_to_angle(temp.x,my.force_x);
my.rot_pan_to = temp.x;
}
}
}
rotate_entity(my.rot_pan_to,1);
c_move(my,my.move_x,vector(my.force_x,my.force_y,0),IGNORE_PASSABLE | GLIDE);
my.push_x = 0;
my.push_y = 0;
}
function handle_camera_lockon()
{
vec_to_angle(temp.x,vec_diff(temp,target_ent.x,my.x));
result = ang(temp.x - camera_pan);
result2 = vec_dist(my.x,target_ent.x) / 10; //how fast the camera spins is based on how far away the player is from the enemy (this stops the camera spinning too fast when the player is further away)
camera_distance = move_variable(camera_distance,camera_real_distance - clamp(result2*3,0,100),5);
result4 = result2/6;
if (abs(result) > 120) { result2 /= abs(result)*0.05; } //result2 determines how fast the camera spins around to meet the player, if the angle from the player to the enemy is greater than 120 degrees from the camera's angle then we start speeding up the spinning
// if (abs(result) < 20) { result2 = 0; } //result2 determines how fast the camera spins around to meet the player, if the angle from the player to the enemy is greater than 120 degrees from the camera's angle then we start speeding up the spinning
result3 = (-50 + result4) * (((1000 - vec_dist(my.x,target_ent.x)) / 2500) + 0.6);
// result3 = -45 * (((1000 - vec_dist(my.x,target_ent.x)) / 2500) + 0.6);
result6 = temp.x + (result3 * sign(result));
camera_spin_speed = result2;
temp.x = ang(result6 - camera_pan) / (5 + camera_spin_speed); //temp is the speed at which the camera turns, it is based on the angular difference, it also moves to the nearest 45 degres from the player's angle, to offset it a little
// temp.x *= vec_dist(camera_focus_point.x,target_ent.x)/40;
result4 = minv(vec_dist(my.x,target_ent.x),400)/400;
result5 = abs(ang(my.pan - camera.pan));
result = clamp(45 - (result4*45),10,45);
vec_set(temp2.pan,my.x);
vec_to_screen(temp2.pan,camera);
if (temp2.pan >= (screen_size.x - 100) || temp2.pan < 100 || result5 > result) {
result2 = 0;
result4 = 1;
if (temp2.pan >= (screen_size.x - 100)) { result2 = (temp2.pan - screen_size.x - 100) * 50; result2 = 50; }
if (temp2.pan < 100) { result2 = abs(100 - temp2.pan) * 50; result2 = 50; }
//player is off screen rotate camera faster
result3 = result2 * 0.5 * (vec_dist(my.x,target_ent.x)/400);
result3 = 5;
if (result5 > result && result2 == 0) { result2 = result; } //result2 = (result5 - result)*10; }
camera_spin_speed_force = move_variable(camera_spin_speed_force,result2,50);
} else {
result = 0.5;
if (abs(ang(camera_pan - camera.pan)) < 3) { result = 5; }
camera_spin_speed_force = move_variable(camera_spin_speed_force,0,5);
}
temp.x *= camera_spin_speed_force;
// if (result5 > result) { temp *= vec_dist(my.x,target_ent.x)/40; }
// temp *= vec_dist(my.x,target_ent.x)/40;
// if (camera_pan > result) { result3 = 1; }
// if (camera_pan < result) { result3 = -1; }
// camera_pan += temp * time_step;
// if (result3 == -1 && camera_pan > result) || (result3 == 1 && camera_pan < result) { camera_pan = result; }
camera_pan = move_rotate_variable(camera_pan,result6,abs(temp.x));
camera.pan = camera_pan;
camera_tilt = -15;
temp.x = fcos(camera_tilt,-camera_distance);
// vec_set(camera_move_to.x,vector(my.x + fcos(camera.pan,temp),my.y + fsin(camera.pan,temp),my.z + 20 + fsin(camera_tilt,-camera_distance)));
vec_set(camera_move_to.x,vector(my.x + fcos(camera.pan,temp.x),my.y + fsin(camera.pan,temp.x),my.z + (my.max_z*0.4) + fsin(camera_tilt,-camera_distance)));
camera_lockon_interpolate = move_variable(camera_lockon_interpolate,0.5,0.02);
temp.x = minv(1,camera_lockon_interpolate * time_step); //changing 0.5 will change how fast the camera moves, at 1 places us at target, this value is what allows the smooth movement
camera.x += temp.x*(camera_move_to.x - camera.x);
camera.y += temp.x*(camera_move_to.y - camera.y);
camera.z += temp.x*(camera_move_to.z - camera.z);
vec_diff(temp.x,camera.x,camera_view_to.x);
vec_normalize(temp.x,16);
vec_add(temp.x,camera.x);
c_trace(vector(my.x,my.y,my.z + (my.max_z/2)),temp.x,IGNORE_ME|IGNORE_PASSABLE|IGNORE_FLAG2);
if (result > 0) {
vec_diff(temp.x,camera_view_to.x,target.x);
vec_normalize(temp.x,16);
vec_set(camera.x,target.x);
vec_add(camera.x,temp.x);
}
camera_view_to_transition = clamp(camera_view_to_transition + 20 * time_step,0,90);
temp.x = my.x - ((my.x - target_ent.x) / 2.4);
temp.y = my.y - ((my.y - target_ent.y) / 2.4);
result = (my.z + (my.max_z*0.4));
temp.z = result - ((result - (target_ent.z + (target_ent.max_z*0.4))) / 4);
vec_lerp(camera_view_to.x,vector(my.x,my.y,my.z + (my.max_z*0.5)),temp.x,sin(camera_view_to_transition));
}
function handle_camera_freemove() {
var tempv = 0;
if (key_w == 1) { tempv = 50 * time_step; }
if (key_s == 1) { tempv = -50 * time_step; }
if (key_shift == 1) { tempv *= 5; }
if (key_ctrl == 1) { tempv /= 5; }
if (key_a == 1) {
result = 50 * time_step;
if (key_shift == 1) { result *= 5; }
if (key_ctrl == 1) { result /= 5; }
camera.x += fcos(camera.pan + 90,result);
camera.y += fsin(camera.pan + 90,result);
}
if (key_d == 1) {
result = 50 * time_step;
if (key_shift == 1) { result *= 5; }
if (key_ctrl == 1) { result /= 5; }
camera.x += fcos(camera.pan - 90,result);
camera.y += fsin(camera.pan - 90,result);
}
camera.x += fcos(camera.tilt,fcos(camera.pan,tempv));
camera.y += fcos(camera.tilt,fsin(camera.pan,tempv));
camera.z += fsin(camera.tilt,tempv);
if (key_ctrl == 1 || mouse_right == 1) {
camera.pan -= mouse_force.x * time_step * 8;
camera.tilt += mouse_force.y * time_step * 8;
}
}
function handle_camera_3rd()
{
//camera_distance = move_variable(camera_distance,camera_real_distance,5);
if (pkey_camera_control == 1) {
camera_pan -= mouse_force.x * 12 * time_step;
camera_tilt += mouse_force.y * 8 * time_step;
}
camera_tilt = clamp(camera_tilt,-30,10);
camera.pan = camera_pan;
temp.x = fcos(camera_tilt,-camera_distance);
vec_set(camera_move_to.x,vector(my.x + fcos(camera.pan,temp.x),my.y + fsin(camera.pan,temp.x),my.z + 20 + fsin(camera_tilt,-camera_distance)));
temp.x = minv(1,0.5 * time_step); //changing 0.5 will change how fast the camera moves, at 1 places us at target, this value is what allows the smooth movement
camera.x += temp.x*(camera_move_to.x - camera.x);
camera.y += temp.x*(camera_move_to.y - camera.y);
camera.z += temp.x*(camera_move_to.z - camera.z);
vec_set(camera_view_to.x,vector(my.x,my.y,my.z + (my.max_z/2)));
vec_diff(temp.x,camera.x,camera_view_to.x);
vec_normalize(temp.x,16);
vec_add(temp.x,camera.x);
c_trace(camera_view_to.x,temp.x,IGNORE_ME|IGNORE_PASSABLE|IGNORE_FLAG2);
if (result > 0) {
vec_diff(temp.x,camera_view_to.x,target.x);
vec_normalize(temp.x,16);
vec_set(camera.x,target.x);
vec_add(camera.x,temp.x);
}
vec_diff(temp.x,camera_view_to.x,camera.x);
vec_to_angle(temp.x,temp.x);
camera.pan = temp.x;
camera.tilt = temp.y + 6;
camera_view_to_transition = 0;
/* camera.pan -= mouse_force.x * 12 * time_step;
camera_tilt += mouse_force.y * 8 * time_step;
camera_tilt = clamp(camera_tilt,-30,10);
temp = fcos(camera_tilt,-camera_distance);
vec_set(camera.x,vector(my.x + fcos(camera.pan,temp),my.y + fsin(camera.pan,temp),my.z + 20 + fsin(camera_tilt,-camera_distance)));
vec_diff(temp.x,camera.x,my.x); //find the vector from the player to the camera
vec_normalize(temp.x,16); //get the magnitude of it's vector to 16 quants and store it in temp
vec_add(temp.x,camera.x); //add the vector (from player to camera) of a magnitude of 16 quants and add it to the camera's position.
trace_mode = IGNORE_ME+IGNORE_PASSABLE+ignore_models;
result = trace(my.x,temp.x); //trace from the player to 16 quants behind the camera.
if (result > 0) {
vec_diff(temp.x,my.x,target.x); //find the vector from the point the trace hit to the player
vec_normalize(temp.x,16); //get the magnitude of this vector to 16 quants and store in temp
vec_set(camera.x,target.x); //place the camera at the trace hit point
vec_add(camera.x,temp.x); //move the camera away from the wall by the vector temp, 16 quants towards the player
}
camera.tilt = camera_tilt;*/
}
function handle_camera_rotation() {
/* camera_view_position.x = move_variable(camera_view_position.x,camera_view_to.x,abs(camera_view_position.x - camera_view_to.x));
camera_view_position.y = move_variable(camera_view_position.y,camera_view_to.y,abs(camera_view_position.y - camera_view_to.y));
camera_view_position.z = move_variable(camera_view_position.z,camera_view_to.z,abs(camera_view_position.z - camera_view_to.z));
vec_diff(temp.x,camera_view_position.x,camera.x);
vec_to_angle(temp.pan,temp.x);
camera.pan = temp.pan;
camera.tilt = temp.tilt + 5;*/
camera_view_position.x = move_variable(camera_view_position.x,camera_view_to.x,abs(camera_view_position.x - camera_view_to.x));
camera_view_position.y = move_variable(camera_view_position.y,camera_view_to.y,abs(camera_view_position.y - camera_view_to.y));
camera_view_position.z = move_variable(camera_view_position.z,camera_view_to.z,abs(camera_view_position.z - camera_view_to.z));
vec_diff(temp.x,camera_view_position.x,camera.x);
vec_to_angle(temp2.pan,temp.x);
camera.pan = temp2.pan;
camera.tilt = temp2.tilt + 6;
}
function handle_camera() {
if (camera_movement_mode == camera_freemove_mode) { handle_camera_freemove(); return; }
if (player_targeting_mode == 1) {
handle_camera_lockon();
} else {
handle_camera_3rd();
}
handle_camera_rotation();
}
function handle_movement() {
//if we are dying, deactivate from being attacked
if (my.state_machine == state_death) { my.emask &= ~ENABLE_SCAN; set(my,PASSABLE); my.entity_type = NULL; return; }
handle_target(); //find nearest target to player, if any, by using c_scan
if (player == my) { handle_player_input(); } else { handle_ai_input(); }
my.attack_delay = move_variable(my.attack_delay,0,1);
if ((my.push_x != 0 || my.push_y != 0) && (my.velocity_x == 0 && my.velocity_y == 0)) { // && my.ai_command_state != ai_command_guard
my.velocity_x += my.push_x;
my.velocity_y += my.push_y;
}
process_state_machines();
process_animation();
process_movement();
if(my.health>0) handle_healthbar();
if(key_a == 1 || key_d == 1 || key_s == 1 || key_w == 1)
{
pXent_getvelocity (me, friction_vec, nullvector);
vec_inverse(friction_vec);
vec_scale(friction_vec, 0.6*time_step*(16./60)*(1-key_shift*0.5) );
vec_set(move_vec, vector( my.velocity_x, my.velocity_y, 0));
vec_normalize(move_vec, 60*time_step*(1+key_shift*0.5) );
vec_rotate(move_vec, my.pan);
pXent_addvelcentral(me, friction_vec);
pXent_addvelcentral(me, move_vec);
pXent_rotate(my,vector(my.pan,0,0),nullvector);
}
if (player == my) { handle_camera(); } //process camera on player controlled entity
}
function find_combatant_statistics() {
reset(my,shield_state);
if (my.statistic_ID == 0) {
my.max_health = 40;
set(my,shield_state);
}
if (my.statistic_ID == 1) { my.max_health = 100; }
if (my.statistic_ID == 10){
// set(my,shield_state);
}
if (player == my) { set(my,FLAG5); my.max_health = 150; } //make the player super strong
if (my.entity_type == type_combatant_friendly && me != player) my.max_health = 45;
my.health = my.max_health;
my.damage = 5;
return;
}
function combatant() {
set(my,FLAG2); //c_trace camera ignores
find_combatant_statistics();
my.emask |= (ENABLE_SCAN|ENABLE_DETECT|ENABLE_ENTITY);
my.event = combatant_scan_event;
ground_entity();
set(my,INVISIBLE);
create_animated_model(my.combatant_model_ID);
my.rot_pan_to = my.pan;
if (player == my) {
wait(5);
attracting_ent = my;
wait(1);
attracting_ent = NULL;
}
pXent_settype(my,PH_RIGID,PH_BOX);
pXent_setbodyflag(me, NX_BF_FROZEN_ROLL | NX_BF_FROZEN_TILT, 1);
pXent_setdamping (me, 50, 50);
pXent_setfriction (me, 0);
pXent_setmass(my, 50);
while (1)
{ //the main loop
while ((vec_dist(my.x,camera.x) > camera.clip_far && player != my) || (freeze_entities != 0) || (freeze_combatants != 0) || (freeze_player != 0 && player == my) || (freeze_non_player != 0 && player != my)) {
temp_panel = ptr_for_handle(my.health_panel); reset(temp_panel,SHOW); wait(1);
}
if (my.state_machine == state_remove) { break; }
animate_ent = ptr_for_handle(my.animated_attach);
if(player!=NULL) panel_var= player.health ;
handle_gravity(); //calculate my.move_z (velocity to move combatant downwards)
handle_movement();
wait(1);
}
wait(-1);
animate_ent = ptr_for_handle(my.animated_attach);
set(animate_ent,TRANSLUCENT);
while (1) {
animate_ent = ptr_for_handle(my.animated_attach);
animate_ent.alpha = move_variable(animate_ent.alpha,0,2);
if (animate_ent.alpha == 0) { ent_remove(animate_ent); ent_remove(my); return; }
wait(1);
}
}
function control_circle_shape() {
my.skill5 += 25 * time_step;
my.skill5 %= 360;
result = (8 + fcos(my.skill5,1)) * 0.1;
if (my.skill1 == 0) { //disappearing
result = 1.5;
}
my.scale_x = move_variable(my.scale_x,result,0.25);
my.scale_y = my.scale_x;
my.scale_z = my.scale_x;
vec_to_angle(temp2.pan,vec_diff(temp,camera.x,my.x));
my.pan = temp2.pan;
my.tilt = temp2.tilt;
}
function lockon_circle() { //targetting image used for player combatant
set(my,PASSABLE);
proc_mode=PROC_LATE;
wait(1);
if (!is(my,FLAG1)) {
//red target
lockon_circle_ent = my;
} else {
//blue target
follow_circle_ent = my;
str_cpy(temp_string,"attackarrow_blue"); str_cat(temp_string,".tga");
ent_morphskin(my,temp_string);
}
my.ambient = 100;
set(my,TRANSLUCENT);
my.alpha = 0;
while (1) {
while ((!player) || (freeze_player != 0) || (freeze_non_player)) { set(my,INVISIBLE); wait(1); }
if (!is(my,FLAG1)) {
target_ent = ptr_for_handle(player.targeted_ent);
if (target_ent && my.skill1 == 0) {
my.skill1 = 2;
str_cpy(temp_string,"attackarrow_target"); str_cat(temp_string,".tga");
ent_morphskin(my,temp_string);
}
result = 0;
if (selected_ent) { if (selected_ent.entity_type != type_combatant_enemy) { result = 1; } }
if ((result == 1 || !target_ent) && (my.skill1 == 2)) {
my.skill1 = 0;
str_cpy(temp_string,"attackarrow_red"); str_cat(temp_string,".tga");
ent_morphskin(my,temp_string);
}
if (!selected_ent && my.skill1 == 1) { my.skill1 = 0; }
}
if (my.skill1 == 0) {
my.alpha = move_variable(my.alpha,0,25);
if (my.alpha <= 0) { set(my,INVISIBLE); }
vec_set(my.x,my.original_x); //place at last known position
} else {
reset(my,INVISIBLE);
result = 100;
if (player_targeting_mode == 0 && !is(my,FLAG1)) { result *= 0.5; }
my.alpha = move_variable(my.alpha,result,25);
if (my.skill1 == 2 && target_ent && !is(my,FLAG1)) {
vec_set(my.x,vector(target_ent.x,target_ent.y,target_ent.z + (target_ent.max_z/2)));
my.z += 15;
}
vec_set(my.original_x,my.x);
}
if (gui_display == 0) { set(my,INVISIBLE); }
result2 = clamp(vec_dist(my.x,camera.x) - 50,0,20000);
vec_diff(temp.x,camera.x,my.x);
vec_normalize(temp.x,result2);
vec_add(my.x,temp.x);
control_circle_shape();
if (my.alpha > 0) {
result = 5;
if (player_targeting_mode == 1 && !is(my,FLAG1)) { result *= -2.5; }
my.roll -= result * time_step;
}
wait(1);
}
}
function control_circle() { //targetting image used for player combatant
set(my,PASSABLE);
proc_mode=PROC_LATE;
wait(1);
str_cpy(temp_string,"attackarrow_yellow"); str_cat(temp_string,".tga");
ent_morphskin(my,temp_string);
// str_cpy(temp_string,"attackarrow_blue"); str_cat(temp_string,".tga");
control_circle_ent = my;
my.ambient = 100;
set(my,TRANSLUCENT);
my.alpha = 0;
while (1) {
while (!player) { set(my,INVISIBLE); wait(1); }
if (!selected_ent && my.skill1 == 1) { my.skill1 = 0; }
if (my.skill1 == 0) {
my.alpha = move_variable(my.alpha,0,25);
if (my.alpha <= 0) { set(my,INVISIBLE); }
vec_set(my.x,my.original_x); //place at last known position
} else {
reset(my,INVISIBLE);
result = 100;
my.alpha = move_variable(my.alpha,result,25);
vec_set(my.original_x,my.x);
}
result2 = clamp(vec_dist(my.x,camera.x) - 50,0,20000);
vec_diff(temp.x,camera.x,my.x);
vec_normalize(temp.x,result2);
vec_add(my.x,temp.x);
control_circle_shape();
if (my.alpha > 0) {
result = 5;
// if (player_targeting_mode == on) { result *= -2.5; }
my.roll -= result * time_step;
}
wait(1);
}
}
function target_circle() { //targetting image used for player combatant and selected entity
set(my,PASSABLE);
// my.bright = on;
proc_mode=PROC_LATE;
set(my,TRANSLUCENT);
my.alpha = 0;
my.scale_x = 4;
my.scale_y = my.scale_x;
my.scale_z = my.scale_x;
set(my,UNLIT);
set(my,BRIGHT);
// my.light = on;
while (1) {
while (!player) { set(my,INVISIBLE); wait(1); }
// target_ent = ptr_for_handle(player.targeted_ent);
if (selected_ent == NULL) {
my.alpha = move_variable(my.alpha,0,50);
if (my.alpha <= 0) { set(my,INVISIBLE); }
} else {
reset(my,INVISIBLE);
result = 60;
my.alpha = move_variable(my.alpha,result,50);
vec_set(my.x,selected_ent.x);
my.z += selected_ent.min_z;
}
my.pan -= 30 * time_step;
wait(1);
}
}
function command_arrow() { //model displayed to show where to move a unit
set(my,PASSABLE);
// my.bright = on;
proc_mode=PROC_LATE;
set(my,TRANSLUCENT);
my.alpha = 0;
set(my,UNLIT);
set(my,LIGHT);
my.ambient = 100;
while (1) {
while (!player || !lockon_circle_ent) { set(my,INVISIBLE); wait(1); }
// target_ent = ptr_for_handle(player.targeted_ent);
result = 0;
if (selected_ent) {
if (selected_ent.entity_type == type_combatant_friendly) { result = 1; }
if (selected_ent.entity_type == type_combatant_enemy) {
if (lockon_circle_ent.skill1 == 1) { lockon_circle_ent.skill1 = 0; }
}
} else {
if (follow_circle_ent.skill1 == 1) { follow_circle_ent.skill1 = 0; }
}
if (result == 0) {
my.alpha = move_variable(my.alpha,0,50);
if (my.alpha <= 0) { set(my,INVISIBLE); }
} else {
reset(my,INVISIBLE);
result = 50;
my.alpha = move_variable(my.alpha,result,50);
vec_set(temp.x,vector(mouse_pos.x,mouse_pos.y,10000));
vec_set(temp6.x,vector(mouse_pos.x,mouse_pos.y,10));
vec_for_screen(temp.x,camera);
vec_for_screen(temp6.x,camera);
// you = player;
// if (selected_ent != NULL) { you = NULL; }
c_trace(temp6.x,temp.x,IGNORE_PASSABLE);
if (you) {
if (you.entity_type == type_combatant_enemy) {
if (my.skill1 == 0) {
lockon_circle_ent.skill1 = 1;
my.skill1 = 1;
}
vec_set(target.x,you.x);
if (my.skill1 == 1) { vec_set(lockon_circle_ent.x,vector(target.x,target.y,target.z + you.max_z)); }
target.z += you.min_z;
if (follow_circle_ent.skill1 == 1) { follow_circle_ent.skill1 = 0; }
if (control_circle_ent.skill1 == 1) { control_circle_ent.skill1 = 0; }
} else {
temp_ent = ptr_for_handle(you.leading_ent);
// if (you.entity_type == type_combatant_friendly && selected_ent != you) && ((you.formation_state == 0) || (you.formation_state != 0 && temp_ent == NULL)) {
if ((you.entity_type == type_combatant_friendly && you != selected_ent) && ((you.formation_state == 0) || (you.formation_state != 0 && temp_ent == NULL)) && (temp_ent != selected_ent)) {
// if (you.entity_type == type_combatant_friendly && you != selected_ent) && ((selected_ent.formation_state != 0 && you.formation_state == 0) || (selected_ent.formation_state == 0)) {
if (my.skill1 == 0) { my.skill1 = 1; }
follow_circle_ent.skill1 = 1;
vec_set(target.x,you.x);
// vec_set(follow_circle_ent.x,vector(you.x,you.y,you.z + you.max_z));
vec_set(follow_circle_ent.x,you.x);
target.z += you.min_z;
if (control_circle_ent.skill1 == 1) { control_circle_ent.skill1 = 0; }
if (lockon_circle_ent.skill1 == 1) { lockon_circle_ent.skill1 = 0; }
} else {
if (you.entity_type == type_combatant_friendly && you == selected_ent) {
control_circle_ent.skill1 = 1;
vec_set(target.x,you.x);
vec_set(control_circle_ent.x,you.x);
target.z += you.min_z;
if (follow_circle_ent.skill1 == 1) { follow_circle_ent.skill1 = 0; }
if (lockon_circle_ent.skill1 == 1) { lockon_circle_ent.skill1 = 0; }
} else {
if (follow_circle_ent.skill1 == 1) { follow_circle_ent.skill1 = 0; }
if (control_circle_ent.skill1 == 1) { control_circle_ent.skill1 = 0; }
if (lockon_circle_ent.skill1 == 1) { lockon_circle_ent.skill1 = 0; }
if (my.skill1 == 1) { my.skill1 = 0; }
}
}
}
if (lockon_circle_ent == 1) { lockon_circle_ent = 0; }
vec_set(my.x,target.x);
my.z += 3;
} else {
vec_set(my.x,target.x);
my.z += 3;
}
}
my.pan -= 5 * time_step;
wait(1);
}
}
//dynamic unit conrol, assign player pointer
function process_combatant_selection_startup() { //right clicking unit and selecting
var store_leader_ID;
var store_new_leader_ID;
var store_selected_ent;
while (1) {
if (player && freeze_player == 0) {
if ((pkey_interact == 1 && interact_press == 0) && (selected_ent || player_targeting_mode == 1)) {
interact_press = 1;
selected_ent = NULL;
player.targeted_ent = 0;
player_targeting_mode = 0;
wait(1);
continue;
}
if (player_targeting_mode == 1) {
// temp_ent = ptr_for_handle(player.targeted_ent);
// if (temp_ent) { selected_ent = temp_ent; }
// wait(1);
// continue;
}
if (pkey_select == 1 && select_press == 0) {
select_press = 1;
vec_set(temp.x,vector(mouse_pos.x,mouse_pos.y,10000));
vec_set(temp6.x,vector(mouse_pos.x,mouse_pos.y,10));
vec_for_screen(temp.x,camera);
vec_for_screen(temp6.x,camera);
// if (selected_ent != NULL) { you = NULL; }
result = c_trace(temp6.x,temp.x,IGNORE_PASSABLE);
if (you) {
if (selected_ent == NULL) {
if (you != player) {
if (you.entity_type == type_combatant_friendly || you.entity_type == type_combatant_enemy) {
selected_ent = you;
}
}
} else {
// if (you.formation_state == 0) {
result = 0;
//order combatant to move to a position
if ((you.entity_type != type_combatant_friendly && you.entity_type != type_combatant_enemy) && selected_ent.entity_type == type_combatant_friendly) {
// if (selected_ent.formation_state == 0) {
vec_set(selected_ent.move_to_x,target.x);
// vec_set(selected_ent.original_x,selected_ent.x);
leader_ent = ptr_for_handle(selected_ent.leading_ent);
result = 1;
selected_ent.ai_command_state = ai_command_guard;
if (leader_ent) { //reset the formation ids
selected_ent.leading_ent = 0;
leader_ent.leader = -1;
leader_ent.formation_amount = 0;
selected_ent.formation_distance = 0;
selected_ent.formation_amount = 0;
selected_ent.formation_follower_ID = 0;
selected_ent.leading_ent = 0;
selected_ent.formation_state = 0;
store_leader_ID = handle(leader_ent);
wait(1); //wait for party to respond to .leader = -1
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = -2;
wait(1); //wait for party to respond to .leader = -2
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = 1;
}
if (key_shift == 0) {
selected_ent = NULL;
}
wait(1);
continue;
// }
}
if (you.entity_type == type_combatant_enemy && selected_ent.entity_type == type_combatant_enemy && you == selected_ent) {
player.targeted_ent = handle(you);
player_targeting_mode = 1;
camera_lockon_interpolate = 0.1;
wait(1);
continue;
}
if (player_targeting_mode == 1 && you.entity_type == type_combatant_enemy && selected_ent.entity_type == type_combatant_enemy && you != selected_ent) {
result5 = combatant_c_scan_distance + 20;
if (vec_dist(player.x,you.x) < result5) {
player.targeted_ent = handle(you);
selected_ent = you;
player_targeting_mode = 1;
camera_lockon_interpolate = 0.1;
wait(1);
continue;
}
}
if (you.entity_type != type_combatant_enemy && selected_ent.entity_type == type_combatant_enemy) {
selected_ent = NULL;
player.targeted_ent = 0;
player_targeting_mode = 0;
wait(1);
continue;
}
if (you.entity_type == type_combatant_enemy && selected_ent.entity_type == type_combatant_friendly) {
selected_ent.ai_command_state = ai_command_chase;
vec_set(selected_ent.move_to_x,you.x);
leader_ent = ptr_for_handle(selected_ent.leading_ent);
if (leader_ent) { //reset the formation ids
selected_ent.leading_ent = 0;
leader_ent.leader = -1;
leader_ent.formation_amount = 0;
selected_ent.formation_distance = 0;
selected_ent.formation_amount = 0;
selected_ent.leading_ent = 0;
selected_ent.formation_state = 0;
selected_ent.formation_follower_ID = 0;
store_leader_ID = handle(leader_ent);
wait(1); //wait for party to respond to .leader = -1
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = -2;
wait(1); //wait for party to respond to .leader = -2
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = 1;
}
if (key_shift == 0) {
selected_ent = NULL; //remove selection
}
wait(1);
continue;
}
if (you.entity_type == type_combatant_friendly && selected_ent == you && selected_ent.entity_type == type_combatant_friendly) {
//take control of friendly combatant
player = you; //use for combatant code
if (key_shift == 0) { selected_ent = NULL; }
player_targeting_mode = 0; //remove lock on
// if (you.leader == 0) { you.formation_state = 0; }
player.ai_command_state = 0;
player.formation_state = 0;
player.formation_amount = 0;
player.leader = 1;
leader_ent = ptr_for_handle(player.leading_ent);
if (leader_ent) { //reset the formation ids
player.leading_ent = 0;
leader_ent.leader = -1;
leader_ent.formation_amount = 0;
player.formation_distance = 0;
player.formation_amount = 0;
player.leading_ent = 0;
player.formation_state = 0;
player.formation_follower_ID = 0;
store_leader_ID = handle(leader_ent);
wait(1); //wait for party to respond to .leader = -1
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = -2;
wait(1); //wait for party to respond to .leader = -2
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = 1;
}
player.formation_state = 0;
wait(1);
continue;
}
temp_ent = ptr_for_handle(you.leading_ent);
if ((you.entity_type == type_combatant_friendly && selected_ent != you) && ((you.formation_state == 0) || (you.formation_state != 0 && temp_ent == NULL)) && (temp_ent != selected_ent) && (selected_ent.entity_type == type_combatant_friendly)) {
// if (selected_ent.formation_state == 0) {
selected_ent.ai_command_state = 0;
leader_ent = ptr_for_handle(selected_ent.leading_ent);
//if we are selecting a new leader and currently have a leader
if (leader_ent && you != leader_ent) {
store_new_leader_ID = handle(you);
selected_ent.leading_ent = handle(you);
selected_ent.formation_distance = 0;
if (leader_ent) { //reset the formation ids
selected_ent.leading_ent = 0;
selected_ent.formation_distance = 0;
selected_ent.formation_amount = 0;
selected_ent.formation_follower_ID = 0;
selected_ent.leading_ent = 0;
selected_ent.formation_state = 0;
store_leader_ID = handle(leader_ent);
wait(1); //wait for party to respond to .leader = -1
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = -1;
leader_ent.formation_amount = 0;
wait(1);
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = -2;
wait(1); //wait for party to respond to .leader = -2
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = 1;
}
selected_ent.formation_amount = 0;
leader_ent = ptr_for_handle(store_new_leader_ID);
selected_ent.leading_ent = handle(leader_ent);
} else {
selected_ent.leading_ent = handle(you);
leader_ent = you;
selected_ent.leading_ent = handle(leader_ent);
}
if (leader_ent && selected_ent.formation_distance == 0) {
leader_ent.formation_amount += 1;
selected_ent.formation_follower_ID = leader_ent.formation_amount + 1; //store our id in formation
selected_ent.formation_distance = 60 + random(50);
}
// }
}
if (result == 0 && key_shift == 0) { selected_ent = NULL; }
}
// }
/* if (you.entity_type == type_combatant_friendly && player.state_machine == state_null) {
player = you;
player_targeting_mode = off; //remove lock on
if (you.leader == 0) { you.formation_state = 0; }
}*/
} else {
// we have struck bsp, order the unit to move to that position
if (selected_ent != NULL)
{
if (selected_ent.entity_type == type_combatant_friendly)
{
vec_set(selected_ent.move_to_x,target.x);
leader_ent = ptr_for_handle(selected_ent.leading_ent);
result = 1;
selected_ent.ai_command_state = ai_command_guard;
if (leader_ent) { //reset the formation ids
selected_ent.leading_ent = 0;
leader_ent.leader = -1;
leader_ent.formation_amount = 0;
selected_ent.formation_distance = 0;
selected_ent.formation_amount = 0;
selected_ent.formation_follower_ID = 0;
selected_ent.leading_ent = 0;
selected_ent.formation_state = 0;
store_leader_ID = handle(leader_ent);
wait(1); //wait for party to respond to .leader = -1
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = -2;
wait(1); //wait for party to respond to .leader = -2
leader_ent = ptr_for_handle(store_leader_ID);
leader_ent.leader = 1;
}
if (key_shift == 0) {
selected_ent = NULL;
}
wait(1);
continue;
}
}
}
}
}
wait(1);
}
}
action combatant_player() {
player = my;
my.leader = 1;
my.entity_type = type_combatant_friendly;
// my.no_strafe = on;
create_health_panel();
str_cpy(temp_string,"target_ring"); str_cat(temp_string,".mdl");
ent_create(temp_string,my.x,target_circle);
str_cpy(temp_string,"commandarrow"); str_cat(temp_string,".mdl");
ent_create(temp_string,my.x,command_arrow);
str_cpy(temp_string,"lockon_display"); str_cat(temp_string,".mdl");
ent_create(temp_string,my.x,lockon_circle);
str_cpy(temp_string,"lockon_display"); str_cat(temp_string,".mdl");
you = ent_create(temp_string,my.x,lockon_circle);
set(you,FLAG1);
str_cpy(temp_string,"lockon_display"); str_cat(temp_string,".mdl");
you = ent_create(temp_string,my.x,control_circle);
set(you,FLAG3);
combatant();
return;
}
//skill1:combatant_behavior_id, determines what type of model is being used, a wolf, a warrior, for animation sets etc
//skill2:movement_speed, speed at which combatant moves
//skill4:statistic_ID, id of stats which determines health etc
//skill6:leader_id, id of leader
//skill7:combatant_model_ID, ID of the actual animated model to attach to the combatant's collision hull, beast, warrior etc
//skill8:ent_formation_id, initial state of formation of entity leader
action combatant_enemy() {
create_health_panel();
if (my.leader > 0) {
find_path();
set_ai_formation(my.ent_formation_id);
}
my.entity_type = type_combatant_enemy;
combatant();
return;
}
action combatant_friendly() {
create_health_panel();
my.entity_type = type_combatant_friendly;
// my.no_strafe = on;
combatant();
return;
}