/*================================================================================ * Please don't change plugin register information. [ZP] Flying Zombie (ver 1.0) Flight operation buttons: W - forward flight A - Flying the left D - right to fly S - Backward flying SPACE - Up to fly CTRL - to fly down ================================================================================*/ #include #include #include #include #include #define PLUGIN_NAME "[ZP] Class:Bat" #define PLUGIN_VERSION "1.0" #define PLUGIN_AUTHOR "Jim" #define GET_ATTACK_DEPLETE_ENERGY //Attacked and injured by human energy will detract from the flight. #define GET_ATTACK_FREEZE_ACTION //Flight by human attacks in a short time to a certain extent the cumulative damage will be temporarily unable to control flight movements. (On top plus / / or the cancellation of the effect) #if defined GET_ATTACK_DEPLETE_ENERGY #define Amount_Of_Damage_Deplete 10.0 //A gun attack by humans, how much damage is accumulated by an energy impairment. #define Damage_Deplete_Energy 5 //Detract from the value of each is the number one energy. #endif #if defined GET_ATTACK_FREEZE_ACTION #define Damage_Check_Time_Range 1.0 //How much time in the cumulative damage caused by certain value, will be temporarily unable to control flight movements. (Unit: seconds) #define Amount_Of_Damage_Freeze 200.0 //The cumulative value of the damage by how much #define Amount_Freeze_Time 1.0 //The length of time a freeze (unit: seconds) #endif const fly_forward_speed = 300 //forward flying speed const fly_left_right_speed = (fly_forward_speed / 3) * 2 //to the left and the speed of flight const fly_up_down_speed = fly_forward_speed / 2 //to the upper and lower flight speed const fly_back_speed = fly_forward_speed / 3 //down flight speed const fly_step_range = 90 //flight range of up and down swing // Bat Zombie Attributes new const zclass_name[] = { "Variant of bat" } new const zclass_info[] = { "Sky Life Flight III" } new const zclass_model[] = { "zombie_source" } new const zclass_clawmodel[] = { "v_knife_zombie.mdl" } const zclass_health = 1500 const zclass_speed = 180 const Float:zclass_gravity = 0.8 const Float:zclass_knockback = 1.85 //new const sound_wings_up[] = { "" } //new const sound_wings_down[] = { "" } new g_zclass_bat, g_max_energy, g_start_energy new Float:player_last_check_time[33] new bool:hit_key[33] new bool:use_fly[33] new fly_energy[33] new bool:fly_step_shift[33], Float:fly_check_time[33] #if defined GET_ATTACK_DEPLETE_ENERGY new Float:get_attack_damage[33] #endif #if defined GET_ATTACK_FREEZE_ACTION new Float:get_attack_damage2[33], Float:damage_check_time[33], bool:can_control[33] #endif public plugin_init() { register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR) g_max_energy = register_cvar("zp_bat_max_energy", "600") //maximum number of accumulated flight energy g_start_energy = register_cvar("zp_bat_start_energy", "20") //open the energy consumption required for the flight value function register_forward(FM_PlayerPostThink, "fw_PlayerPostThink", 1) register_forward(FM_StartFrame, "fw_StartFrame") RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage") register_event("ResetHUD","NewRound","be") register_event("DeathMsg", "Death", "a") } public plugin_precache() { //engfunc(EngFunc_PrecacheSound, sound_wings_up) //engfunc(EngFunc_PrecacheSound, sound_wings_down) g_zclass_bat = zp_register_zombie_class(zclass_name, zclass_info, zclass_model, zclass_clawmodel, zclass_health, zclass_speed, zclass_gravity, zclass_knockback) } public zp_user_infected_post(id, infector) { if (zp_get_user_zombie_class(id) == g_zclass_bat) { client_print(id, print_chat, "Press E key to open or close the flight capabilities, the flight will consume energy, the flight will slowly back off the energy.") } } public zp_user_humanized_post(id) { hit_key[id] = false if (use_fly[id]) { use_fly[id] = false fm_set_user_gravity(id, zclass_gravity) } fly_energy[id] = get_pcvar_num(g_max_energy) #if defined GET_ATTACK_DEPLETE_ENERGY get_attack_damage[id] = 0.0 #endif if (task_exists(id)) remove_task(id) } public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type) { // Non-player damage or self damage if (victim == attacker || !is_user_connected(attacker)) return HAM_IGNORED; if (!zp_get_user_zombie(victim) || (zp_get_user_zombie_class(victim) != g_zclass_bat)) return HAM_IGNORED; if (zp_get_user_nemesis(victim)) return HAM_IGNORED; if (zp_get_user_zombie(attacker) == zp_get_user_zombie(victim)) return HAM_IGNORED; if (!(damage_type & DMG_BULLET)) return HAM_IGNORED; #if defined GET_ATTACK_DEPLETE_ENERGY get_attack_damage[victim] += damage while (get_attack_damage[victim] > Amount_Of_Damage_Deplete) { fly_energy[victim] = max(fly_energy[victim] -= Damage_Deplete_Energy, 0) get_attack_damage[victim] -= Amount_Of_Damage_Deplete } #endif #if defined GET_ATTACK_FREEZE_ACTION if (can_control[victim]) { get_attack_damage2[victim] += damage if (get_attack_damage2[victim] >= Amount_Of_Damage_Freeze) { can_control[victim] = false remove_task(victim) set_task(Amount_Freeze_Time, "get_damage_cooldown", victim) } } #endif return HAM_IGNORED; } public fw_StartFrame() { //Check the layout to set the time, to prevent too fast refresh static Float:last_check_time if (get_gametime() - last_check_time < 0.5) return; last_check_time = get_gametime() static id for (id = 1; id <= 32; id++) { if (!is_user_alive(id) || !zp_get_user_zombie(id) || (zp_get_user_zombie_class(id) != g_zclass_bat)) continue; if (zp_get_user_nemesis(id)) continue; //Check function is using the flight if (use_fly[id]) { if (fly_energy[id] > 0) { static Float:velocity[3], speed pev(id, pev_velocity, velocity) speed = floatround(vector_length(velocity)) if (speed == fly_forward_speed) { fly_energy[id] = max(fly_energy[id] - 5, 0) } else if (speed >= fly_left_right_speed) { fly_energy[id] = max(fly_energy[id] - 4, 0) } else if (speed >= fly_up_down_speed) { fly_energy[id] = max(fly_energy[id] - 3, 0) } else if (speed >= fly_back_speed) { fly_energy[id] = max(fly_energy[id] - 2, 0) } else { fly_energy[id] = max(fly_energy[id] - 1, 0) } } if (fly_energy[id] == 0) { use_fly[id] = false fm_set_user_gravity(id, zclass_gravity) client_print(id, print_center, "The energy consumption of your flight has been light it!") } } else { if (fly_energy[id] < get_pcvar_num(g_max_energy)) { static Float:velocity[3], speed pev(id, pev_velocity, velocity) speed = floatround(vector_length(velocity)) if (speed > (zclass_speed * 0.6)) { fly_energy[id] = min(fly_energy[id] + 1, get_pcvar_num(g_max_energy)) } else if (speed > (zclass_speed * 0.1)) { fly_energy[id] = min(fly_energy[id] + 2, get_pcvar_num(g_max_energy)) } else { static button button = pev(id, pev_button) if (button & IN_DUCK) fly_energy[id] = min(fly_energy[id] + 4, get_pcvar_num(g_max_energy)) else fly_energy[id] = min(fly_energy[id] + 3, get_pcvar_num(g_max_energy)) } } } show_message_center(id, "Flight energy:%d", fly_energy[id]) } } public fw_PlayerPostThink(id) { if (!is_user_alive(id) || !zp_get_user_zombie(id) || (zp_get_user_zombie_class(id) != g_zclass_bat)) return PLUGIN_CONTINUE if (zp_get_user_nemesis(id)) return PLUGIN_CONTINUE static button, oldbutton button = pev(id, pev_button) oldbutton = pev(id, pev_oldbuttons) if ((button & IN_USE) && (oldbutton & IN_USE)) { if (!hit_key[id]) { hit_key[id] = true if (!use_fly[id]) { if (fly_energy[id] < get_pcvar_num(g_start_energy)) { client_print(id, print_center, "Lack of energy your flight! Can not open the flight capabilities. (At the cost of energy open% d)", get_pcvar_num(g_start_energy)) return PLUGIN_CONTINUE } if (is_user_on_ground(id)) { client_print(id, print_center, "Must first jumped off the ground to open the flight features!") return PLUGIN_CONTINUE } use_fly[id] = true fm_set_user_gravity(id, -0.01) fly_energy[id] -= get_pcvar_num(g_start_energy) client_print(id, print_center, "You have opened the flight capabilities.") #if defined GET_ATTACK_FREEZE_ACTION can_control[id] = true get_attack_damage2[id] = 0.0 #endif } else { use_fly[id] = false fm_set_user_gravity(id, zclass_gravity) client_print(id, print_center, "You have been flying off the functions.") } } } else { hit_key[id] = false } if (use_fly[id]) { if (is_user_on_ground(id)) { use_fly[id] = false fm_set_user_gravity(id, zclass_gravity) client_print(id, print_center, "You've landed.") } if ((get_gametime() - fly_check_time[id]) > 0.5) { new Float:velocity1[3] pev(id, pev_velocity, velocity1) if (fly_step_shift[id]) { fly_step_shift[id] = false velocity1[2] += float(fly_step_range) //PlaySound(id, sound_wings_up) } else { fly_step_shift[id] = true velocity1[2] -= float(fly_step_range) //PlaySound(id, sound_wings_down) } set_pev(id, pev_velocity, velocity1) fly_check_time[id] = get_gametime() } #if defined GET_ATTACK_FREEZE_ACTION if (!can_control[id]) return PLUGIN_CONTINUE if ((get_gametime() - damage_check_time[id]) > Damage_Check_Time_Range) { get_attack_damage2[id] = 0.0 damage_check_time[id] = get_gametime() } #endif if (get_gametime() - player_last_check_time[id] < 0.2) return PLUGIN_CONTINUE player_last_check_time[id] = get_gametime() new Float:velocity[3], bool:have_move have_move = false if (button & IN_FORWARD) { have_move = true velocity_by_aim(id, fly_forward_speed, velocity) set_pev(id, pev_velocity, velocity) } if (button & IN_BACK) { have_move = true velocity_by_aim(id, fly_back_speed, velocity) xs_vec_mul_scalar(velocity, -1.0, velocity) set_pev(id, pev_velocity, velocity) } if (button & IN_MOVELEFT) { have_move = true velocity_by_force_angle(id, fly_left_right_speed, 0, 90.0, velocity) set_pev(id, pev_velocity, velocity) } if (button & IN_MOVERIGHT) { have_move = true velocity_by_force_angle(id, fly_left_right_speed, 0, -90.0, velocity) set_pev(id, pev_velocity, velocity) } if (button & IN_JUMP) { have_move = true velocity[0] = velocity[1] = 0.0 velocity[2] = float(fly_up_down_speed) set_pev(id, pev_velocity, velocity) } if (button & IN_DUCK) { have_move = true velocity[0] = velocity[1] = 0.0 velocity[2] = float(0 - fly_up_down_speed) set_pev(id, pev_velocity, velocity) } if (!have_move) { new speed pev(id, pev_velocity, velocity) speed = floatround(vector_length(velocity)) if (speed > 0) { xs_vec_mul_scalar(velocity, 0.5, velocity) set_pev(id, pev_velocity, velocity) } } } return PLUGIN_CONTINUE } #if defined GET_ATTACK_FREEZE_ACTION public get_damage_cooldown(id) { if (use_fly[id]) { can_control[id] = true get_attack_damage2[id] = 0.0 damage_check_time[id] = get_gametime() } } #endif public client_connect(id) { hit_key[id] = false use_fly[id] = false fly_energy[id] = get_pcvar_num(g_max_energy) #if defined GET_ATTACK_DEPLETE_ENERGY get_attack_damage[id] = 0.0 #endif return PLUGIN_CONTINUE } public client_disconnect(id) { hit_key[id] = false use_fly[id] = false fly_energy[id] = get_pcvar_num(g_max_energy) #if defined GET_ATTACK_DEPLETE_ENERGY get_attack_damage[id] = 0.0 #endif return PLUGIN_CONTINUE } public NewRound(id) { hit_key[id] = false use_fly[id] = false fly_energy[id] = get_pcvar_num(g_max_energy) #if defined GET_ATTACK_DEPLETE_ENERGY get_attack_damage[id] = 0.0 #endif } public Death() { new player = read_data(2) hit_key[player] = false if (use_fly[player]) { use_fly[player] = false fm_set_user_gravity(player, zclass_gravity) } fly_energy[player] = get_pcvar_num(g_max_energy) #if defined GET_ATTACK_DEPLETE_ENERGY get_attack_damage[player] = 0.0 #endif if (task_exists(player)) remove_task(player) } show_message_center(target, const message[], any:...) { new buffer[256] vformat(buffer, sizeof buffer - 1, message, 3) message_begin(MSG_ONE, get_user_msgid("StatusText"), {0, 0, 0}, target) write_byte(0) write_string(buffer) message_end() } /* PlaySound(index, const sound[]) { if (equal(sound[strlen(sound)-4], ".mp3")) client_cmd(index, "mp3 play ^"sound/%s^"", sound) else client_cmd(index, "spk ^"%s^"", sound) } */ stock bool:is_user_on_ground(index) { if (pev(index, pev_flags) & FL_ONGROUND) return true; return false; } stock fm_set_user_gravity(index, Float:gravity = 1.0) { set_pev(index, pev_gravity, gravity); return 1; } stock velocity_by_force_angle(id, force, height, Float:angle, Float:new_velocity[3]) { new Float:entity_angles[3] pev(id, pev_angles, entity_angles) entity_angles[1] += angle while (entity_angles[1] < 0.0) entity_angles[1] += 360.0 new Float:v_length v_length = float(force) new_velocity[0] = v_length * floatcos(entity_angles[1], degrees) new_velocity[1] = v_length * floatsin(entity_angles[1], degrees) new_velocity[2] = float(height) }