--enemy script by smallg --use with ally.lua --how close player or his allies can get before the enemy is alerted local alert_range = 1200 --how much damage is done with 1 shot local bullet_damage = 25 local target = {} local bullet_target = {} local bullet = {} local bullet_dis = {} local closest_ally = {} local soundplaying = {} local hit = {} first_enemy = 0 enemy_true = {} function enemy_init(e) enemy_true[e] = 1 target[e] = 0 bullet_target[e] = 0 bullet_dis[e] = 0 soundplaying[e] = 0 bullet[e] = 0 hit[e] = 0 closest_ally[e] = 99999 if first_enemy == 0 then first_enemy = e end last_enemy = e bullet[e] = ((last_enemy - first_enemy) + 1) + e CharacterControlUnarmed(e) end function enemy_main(e) EntObjNo = g_Entity[e]['obj']; if bullet[e] ~= nil and bullet_target[e] ~= nil and target[e] ~= nil then --find initial target (player's allies) for ally = first_ally, last_ally do if g_Entity[ally] ~= nil then if ally_true[ally] == 1 then if g_Entity[ally]['health'] > 0 then --if a target is in alert range if GetDistance(e,ally) < alert_range or AIGetEntityHeardSound(EntObjNo) == 1 then --compare distance with closest distance and if closer then update to new target if GetDistance(e,ally) < closest_ally[e] then closest_ally[e] = GetDistance(e,ally) target[e] = ally bullet_target[e] = ally end end end end end end --check if player is nearer than closest ally and change target to him if so (if player also in alert range) if GetPlayerDistance(e) < closest_ally[e] and GetPlayerDistance(e) < alert_range then CharacterControlArmed(e) RotateToPlayer(e) --if enemy can see player then shoot at him if g_Entity[e]['plrvisible'] == 1 then FireWeapon(e) end --player in vision closest_ally[e] = 9999999 target[e] = 0 bullet[e] = 0 bullet_target[e] = 0 --move towards player SetCharacterToRun(e) AIEntityGoToPosition(EntObjNo,g_PlayerPosX,g_PlayerPosZ) --if within 1/2 alert range than stop moving forward if GetPlayerDistance(e) < alert_range / 2 then AIEntityStop(EntObjNo) end --near player end --targeting player --if target found if target[e] > 0 then --check it's health is still above 0 if g_Entity[target[e]]['health'] > 0 then --play aggro sound if soundplaying[e] == 0 then PlayCharacterSound(e,"onHurtPlayer") soundplaying[e] = 1 end --sound playing RotateToEntity(e,target[e]) --if bullet not created then create it now if bullet[e] == 0 then --get the entity number of the bullet bullet[e] = ((last_enemy - first_enemy) + 1) + e GravityOff(bullet[e]) --move the bullet to the enemy's location SetPosition(bullet[e],g_Entity[e]['x'],g_Entity[e]['y']+40,g_Entity[e]['z']) --optional to show hidden bullets (for debug/testing) --Spawn(bullet[e]) bullet_target[e] = target[e] --play gunshot noise here PlaySoundIfSilent(e,1) end --bullet created CharacterControlArmed(e) --move to target if GetDistance(e,target[e]) > alert_range / 2 then SetCharacterToRun(e) AIEntityGoToPosition(EntObjNo,g_Entity[target[e]]['x'],g_Entity[target[e]]['z']) --stop if we get 1/2 close to target elseif GetDistance(e,target[e]) < alert_range / 2 then AIEntityStop(EntObjNo) end --move to target --reset target if GetDistance(e,target[e]) > alert_range or g_Entity[target[e]]['health'] < 1 then closest_ally[e] = 9999999 target[e] = 0 soundplaying[e] = 0 end --out of alert range or dead end --target still alive end --target acquired --move and check bullet impact if bullet[e] ~= nil and bullet[e] > 0 then if bullet_target[e] ~= nil and bullet_target[e] > 0 then --update bullet for a while so it travels in correct direction if bullet_dis[e] < 5 then RotateToEntity(bullet[e],bullet_target[e]) end --bullet dis MoveForward(bullet[e],1500) bullet_dis[e] = bullet_dis[e] + 1 --check if bullet hits its target if GetDistance(bullet[e],bullet_target[e]) < 175 and hit[e] == 0 then --reduce target health by bullet damage SetEntityHealth(bullet_target[e],g_Entity[bullet_target[e]]['health'] - bullet_damage) hit[e] = 1 end --bullet hits --check if bullet has reached it's max travel distance and reset if so if bullet_dis[e] > 60 then bullet[e] = 0 bullet_target[e] = 0 bullet_dis[e] = 0 hit[e] = 0 end --bullet max distance end --error check end --error check end --error check end --main function enemy_exit(e) PlayCharacterSound(e,"onDeath") end function GetDistance(e,v) if g_Entity[e] ~= nil and g_Entity[e] ~= 0 and g_Entity[v] ~= nil and g_Entity[v] ~= 0 then local disx = g_Entity[e]['x'] - g_Entity[v]['x'] local disz = g_Entity[e]['z'] - g_Entity[v]['z'] local disy = g_Entity[e]['y'] - g_Entity[v]['y'] return math.sqrt(disx^2 + disz^2 + disy^2) end end function RotateToEntity(e,v) if g_Entity[e] ~= nil and g_Entity[e] ~= 0 and g_Entity[v] ~= nil and g_Entity[v] ~= 0 then local x = g_Entity[v]['x'] - g_Entity[e]['x'] local z = g_Entity[v]['z'] - g_Entity[e]['z'] local angle = math.atan2(x,z) angle = angle * (180.0 / math.pi) if angle < 0 then angle = 360 + angle elseif angle > 360 then angle = angle - 360 end SetRotation(e,0,angle,0) return angle end end