--ally script by smallg --use with enemy.lua script --how close an enemy can get before the ally is alerted local alert_range = 1200 --how much damage is applied on a hit local bullet_damage = 25 local target = {} local closest_enemy = {} local bullet = {} local bullet_dis = {} first_ally = 0 local bullet_target = {} local soundplaying = {} local hit = {} ally_true = {} function ally_init(e) ally_true[e] = 1 soundplaying[e] = 0 target[e] = 0 bullet[e] = 0 bullet_dis[e] = 0 bullet_target[e] = 0 hit[e] = 0 if first_ally == 0 then first_ally = e end last_ally = e closest_enemy[e] = 999999 CharacterControlStand(e) SetCharacterSound(e,"soldier") end function ally_main(e) EntObjNo = g_Entity[e]['obj']; if bullet[e] ~= nil and bullet_target[e] ~= nil and target[e] ~= nil then --find initial target for enemy = first_enemy, last_enemy do if g_Entity[enemy] ~= nil then if enemy_true[enemy] == 1 then if g_Entity[enemy]['health'] > 0 then --if enemy in range if GetDistance(e,enemy) < alert_range or AIGetEntityHeardSound(EntObjNo) == 1 then --if new enemy closer than last closest if GetDistance(e,enemy) < closest_enemy[e] then closest_enemy[e] = GetDistance(e,enemy) target[e] = enemy bullet_target[e] = enemy end --closer? end --in range? end --alive? end --enemy? end --error check end --for enemy loop --target found if target[e] > 0 then if soundplaying[e] == 0 then PlayCharacterSound(e,"onHurtPlayer") soundplaying[e] = 1 end --sound playing RotateToEntity(e,target[e]) --if bullet not create then create it now if bullet[e] == 0 then --get bullet entity number bullet[e] = ((last_ally - first_ally) + 1) + e GravityOff(bullet[e]) --place bullet at ally's location SetPosition(bullet[e],g_Entity[e]['x'],g_Entity[e]['y']+40,g_Entity[e]['z']) --optional show bullet for tests --Spawn(bullet[e]) bullet_target[e] = target[e] --play gunshot noise 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 close to target elseif GetDistance(e,target[e]) < alert_range / 2 then AIEntityStop(EntObjNo) end --move to target --reset target if he's out of range or dead if GetDistance(e,target[e]) > alert_range or g_Entity[target[e]]['health'] < 1 then closest_enemy[e] = 9999999 target[e] = 0 soundplaying[e] = 0 end --out of alert range or dead --if no target and player not nearby elseif GetPlayerDistance(e) > 500 then CharacterControlUnarmed(e) RotateToPlayer(e) --if player far away or nearby noises then run to player to help him if AIGetEntityHeardSound(EntObjNo) == 1 or GetPlayerDistance(e) > 750 then SetCharacterToRun(e) else SetCharacterToWalk(e) end --far away from player? AIEntityGoToPosition(EntObjNo,g_PlayerPosX,g_PlayerPosZ) --if near player then turn to face same way as him elseif GetPlayerDistance(e) < 500 then AIEntityStop(EntObjNo) SetRotation(e,0,g_PlayerAngY,0) end --target acquired --move and check bullet impact if bullet[e] > 0 then if bullet_target[e] ~= 0 then --set bullet rotation so it's heading to target for a while (improves accuracy) if bullet_dis[e] < 5 then RotateToEntity(bullet[e],bullet_target[e]) end MoveForward(bullet[e],1500) bullet_dis[e] = bullet_dis[e] + 1 --if target is hit if GetDistance(bullet[e],bullet_target[e]) < 175 and hit[e] == 0 then --reduce target hp by bullet damage SetEntityHealth(bullet_target[e],g_Entity[bullet_target[e]]['health'] - bullet_damage) hit[e] = 1 end --target hit? --if bullet reaches max distance then reset it if bullet_dis[e] > 60 then bullet[e] = 0 bullet_target[e] = 0 bullet_dis[e] = 0 hit[e] = 0 end --bullet dis end --error check end --error check end --error check end --main function ally_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