itatsu's Bots 0.20 + bot types
itatsu's Bots 0.20 personalities variant
Original work by itatsu
Feb.2.2009
Hold down left mousebutton and drag to scroll
Left click to select a bot
Press Space to pause/resume
Press R to free the viewpoint
0.15よりずいぶん軽くなりました。
次の目標:AIや画面の改良など
Botsのアップグレード機能を追加すればどうかな...
// itatsu's Bots 0.20 personalities variant
// Original work by itatsu
// Feb.2.2009
//
// Hold down left mousebutton and drag to scroll
// Left click to select a bot
// Press Space to pause/resume
// Press R to free the viewpoint
//
// 0.15よりずいぶん軽くなりました。
// 次の目標:AIや画面の改良など
// Botsのアップグレード機能を追加すればどうかな...
//
package {
import flash.display.*;
import flash.events.*;
[SWF(width="465", height="465", backgroundColor="30", frameRate="60")]
public class MyBots extends Sprite {
public function MyBots() {
global = this;
stage.quality = StageQuality.HIGH;
Initialize();
global.addEventListener(Event.ENTER_FRAME, Update);
stage.addEventListener(MouseEvent.CLICK, MouseClick);
stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseDown);
stage.addEventListener(MouseEvent.MOUSE_MOVE, MouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, MouseUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import flash.filters.*;
// Global object
var global:Sprite;
// Main text field
var tField:TextField = new TextField;
// Sub text field
var stField:TextField = new TextField;
// Frame ticks
var ticks:uint;
// Bots vector
var bots:Vector.<Bot> = new Vector.<Bot>();
var botsactive:uint = 0;
// Bullets vector
var bullets:Vector.<Bullet> = new Vector.<Bullet>();
// Viewpoint
var viewpoint:Point = new Point(0, 0); // Top left of FOV
var tempviewpoint:Point = new Point(0, 0); // Top left of FOV
var curviewpoint:Point = new Point(0, 0); // Top left of FOV
// Mousedownpoint
var mousedownpoint:Point = new Point(0, 0);
// Selected bot
var selectedbot:Bot;
// Paused?
var paused:Boolean = false;
// Bot count from start
var botcount:uint = 0;
// Map size
const mapsizex:uint = 1000;
const mapsizey:uint = 1000;
// Performance related
const maxbots:uint = 15;
// AI types:
// 0 - normal (more hate towards more kills, distance falloff)
// 1 - god (more hate towards more kills, no distance falloff)
// 2 - sniper (attacks targets with the most distance)
// 3 - racist (hates attackers of racists, hates other racists less)
// 4 - hater (normal, but hates three times as much)
// 5 - relentless (picked target gets 60 seconds of hate)
// Bots type array (Blame me for all of this)
var bottotalprob:uint;
var bottypes:Array = [
// Name , maxhp, type, speed, turn, shotspeed, bdmg, bspeed, blife, bdev, shield, regen, prob, color
Bot.StatInstance("God" , 750, 1, 2.0, 2.0, 5, 24.0, 5.0, 75, 12.0, 5.0, 0.30, 2, 0xffff80),
Bot.StatInstance("Demigod", 500, 1, 2.0, 2.0, 6, 22.0, 4.8, 72, 15.0, 4.0, 0.25, 5, 0xeeee50),
Bot.StatInstance("Jerk" , 200, 4, 1.3, 1.2, 8, 15.0, 4.2, 64, 18.0, 2.0, 0.12, 50, 0x80ffff),
Bot.StatInstance("Speeder", 80, 0, 2.5, 2.0, 7, 15.0, 4.5, 40, 15.0, 0.0, 0.22, 100, 0xff80ff),
Bot.StatInstance("Tank" , 400, 0, 0.4, 0.7, 8, 13.0, 4.0, 60, 20.0, 5.0, 0.15, 100, 0x80ff80),
Bot.StatInstance("Sniper" , 150, 2, 0.9, 1.2, 80, 60.0, 13.0, 240, 4.0, 1.0, 0.10, 60, 0x8080ff),
Bot.StatInstance("Racist" , 180, 3, 1.0, 1.2, 3, 8.0, 5.0, 18, 40.0, 0.0, 0.16, 200, 0xffffff),
Bot.StatInstance("Rager" , 300, 5, 1.1, 1.0, 9, 11.0, 3.8, 45, 18.0, 2.0, 0.12, 75, 0xff8080),
Bot.StatInstance("Normal" , 100, 0, 1.0, 1.0, 8, 15.0, 4.0, 60, 20.0, 1.0, 0.10, 1000, 0x808080),
];
var botnames:Array = [
["Zeus", "Poseidon", "Hades", "Hestia", "Ares", "Athena", "Apollo", "Aphrodite", "Hermes", "Artemis", "Hephaestus"],
["Achilles", "Amphion", "Britomartis", "Cycnus", "Gilgamesh", "Helen", "Hercules", "Lacedaemon", "Orion", "Perseus", "Sarpedon", "Tityas", "Zetes", "Zethus"],
["You", "Me", "Them", "Us", "Her", "Him", "They", "We", "I", "It" ],
["Ascari", "Mustang", "Viper", "Corvette", "Veyron", "Europa", "Spyder", "RX-8", "Aurian", "Impreza"],
["M1A1", "Tiger", "Panzer", "T72", "T62", "M4A1", "Challenger 2", "M60", "T34"],
["30-06", "308", "50", "9mm", "44 Magnum", "357", "22", "12 Gauge", "410", "38 Special"],
["Billy Bob", "Billy Joe", "Joey Bob"],
["Hate", "Death", "Pain", "Murderer", "Killer", "Revenge", "Vengeance", "Hunter", "Predator"],
["Normal", "Conformist", "Clone", "Generic", "Common"]
];
// Bullets parameters
const CollisionDistance:Number = 85.0;
const sCollisionDistance:Number = Math.sqrt(85.0);
const SafeDistance:Number = 12.0;
// Initialize
function Initialize():void {
var tFormat:TextFormat = new TextFormat;
tFormat.font = "Arial";
tFormat.bold = false;
tFormat.color = 0xffffff;
tFormat.size = 11;
tFormat.align = TextFormatAlign.LEFT;
tField.defaultTextFormat = tFormat;
tField.selectable = false;
tField.x = 5;
tField.y = 428;
tField.width = 460;
tField.antiAliasType = AntiAliasType.ADVANCED;
stField.defaultTextFormat = tFormat;
stField.selectable = false;
stField.x = 370;
stField.y = 105;
stField.width = 95;
stField.height = 360;
stField.antiAliasType = AntiAliasType.ADVANCED;
// calc total prob for bot generation
bottotalprob = 0;
for each (var bot:Bot in bottypes)
bottotalprob += bot.prob;
}
// Main Update
function Update(evt:Event):void {
while (global.numChildren > 0) {
global.removeChildAt(0);
}
if (!paused) {
ticks++;
UpdateAction();
UpdateWorld();
}
Draw();
}
// Update bots action
function UpdateAction():void {
UpdateBotsAI();
}
// Update world status
function UpdateWorld():void {
// Generate bots
// Cheat
if (ticks == 1) {
GenBotIndex(0); // God
}
if (ticks % 10 == 0) {
if (botsactive < maxbots)
GenBot();
}
//
UpdateBots();
UpdateBullets();
CollisionCheckes();
// Rubbish collecting
CollectBots();
CollectBullets();
}
// Draw
function Draw():void {
UpdateViewpoint();
DrawMap();
DrawBots();
DrawBullets();
DrawMinimap();
DrawSelectedBot();
DrawBotStatus();
DrawTextField();
DrawPaused();
}
// Update bots decision
function UpdateBotsAI():void {
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (!bots[i].exist)
continue;
var aitype:uint = bots[i].type;
if (bots[i].target == null || bots[i].targethate <= 0)
{
// find something to hate
for (var j:uint = 0; j < len; j++) {
if (i == j || !bots[j].exist)
continue;
var dist:Number = Distance(bots[j].pos, bots[i].pos, 10000);
var hate:uint = 300;
// add hate for kills (except sniper/racist)
if (aitype != 2 && aitype != 3)
hate += 90 * bots[j].kills
// modify distance for gods and snipers
if (aitype == 1)
dist = 0; // Gods see all
else if (aitype == 2)
dist = 40000 - dist; // invert distance
if (hate < (dist / 200))
hate = 1;
else
hate -= dist / 200;
// racist logic
if (aitype == 3) {
if (bots[j].type == 3)
hate /= 5;
else if (bots[j].target != null && bots[j].target != bots[i] && bots[j].type == 3)
hate *= 2;
}
if (hate > bots[i].targethate) {
bots[i].target = bots[j];
bots[i].targethate = hate;
}
}
// found something so do per extra ai stuff?
if (bots[i].target != null) {
if (aitype == 2 && bots[i].targethate > 600)
bots[i].targethate = 600;
if (aitype == 4)
bots[i].targethate *= 3;
else if (aitype == 5)
bots[i].targethate = 3600;
}
}
else
{
var targ:Bot = bots[i].target;
if (targ.exist)
{
bots[i].FaceToPosition(targ.pos);
bots[i].dir = (bots[i].dir + 360) % 360;
bots[i].targethate--;
}
else
bots[i].targethate = 0;
}
}
}
// Update bots
function UpdateBots():void {
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (!bots[i].exist)
continue;
// regen
bots[i].hp += bots[i].regen;
if (bots[i].hp > bots[i].maxhp) bots[i].hp = bots[i].maxhp;
// move
MoveBot(i);
// shoot
var genpos:Point = new Point;
genpos.x = bots[i].pos.x;
genpos.y = bots[i].pos.y;
genpos.x += Math.sin(bots[i].dir / 180 * Math.PI) * SafeDistance;
genpos.y -= Math.cos(bots[i].dir / 180 * Math.PI) * SafeDistance;
if (ticks % bots[i].shotspeed == 0) {
GenBullet(bots[i], genpos,
bots[i].dir + Math.random() * bots[i].bdev * 2 - bots[i].bdev, // 散布界
bots[i].bdamage, bots[i].bspeed, bots[i].blifespan
);
}
}
}
// Move specific bot
function MoveBot(no:uint):void {
// Do move
bots[no].pos.x += Math.sin(bots[no].dir / 180 * Math.PI) * bots[no].speed;
bots[no].pos.y -= Math.cos(bots[no].dir / 180 * Math.PI) * bots[no].speed;
// Loop
if (bots[no].pos.x < 0) bots[no].pos.x += mapsizex
if (bots[no].pos.x > mapsizex) bots[no].pos.x -= mapsizex;
if (bots[no].pos.y < 0) bots[no].pos.y += mapsizey;
if (bots[no].pos.y > mapsizey) bots[no].pos.y -= mapsizey;
}
// Update bullets
function UpdateBullets():void {
var len:uint = bullets.length;
for (var i:uint = 0; i < len; i++) {
// move
MoveBullet(i);
// life
bullets[i].lifetime++;
if (bullets[i].lifetime >= bullets[i].lifespan) {
bullets[i].exist = false;
}
}
}
// Move specific bullet
function MoveBullet(no:uint):void {
// Do move
bullets[no].pos.x += Math.sin(bullets[no].dir / 180 * Math.PI) * bullets[no].speed;
bullets[no].pos.y -= Math.cos(bullets[no].dir / 180 * Math.PI) * bullets[no].speed;
// Loop
if (bullets[no].pos.x < 0) bullets[no].pos.x += mapsizex;
if (bullets[no].pos.x > mapsizex) bullets[no].pos.x -= mapsizex;
if (bullets[no].pos.y < 0) bullets[no].pos.y += mapsizey;
if (bullets[no].pos.y > mapsizey) bullets[no].pos.y -= mapsizey;
}
// Collision detect
function CollisionCheckes():void {
var len:uint = bullets.length;
for (var i:uint = 0; i < len; i++) {
var target:int = CollisionCheck(i);
if (target > -1) {
var dam:Number = bullets[i].damage - bots[target].shield;
if (dam < 0) dam = 0;
bots[target].hp -= dam;
bots[target].AddHate(bullets[i].bot, dam * 4);
bullets[i].exist = false;
if (bots[target].hp <= 0) {
bots[target].exist = false;
botsactive--;
bullets[i].bot.kills++;
bullets[i].bot.cash += 50;
}
}
}
}
function CollisionCheck(no:uint):int {
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (!bots[i].exist)
continue;
var dist:Number = Distance(bullets[no].pos, bots[i].pos, sCollisionDistance);
if (dist <= CollisionDistance && dist > 0) {
return i;
}
}
return -1;
}
// Rubbish collecting
function CollectBots():void {
/*
var _bots:Vector.<Bot> = new Vector.<Bot>();
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (bots[i].exist) {
_bots.push(bots[i]);
}
else bots[i] = null;
}
bots = _bots;
*/
}
function CollectBullets():void {
var _bullets:Vector.<Bullet> = new Vector.<Bullet>();
var len:uint = bullets.length;
for (var i:uint = 0; i < len; i++) {
if (bullets[i].exist) {
_bullets.push(bullets[i]);
}
else bullets[i] = null;
}
bullets = _bullets;
}
function GenBotIndex(idx:uint):void {
var len:uint = bots.length;
var newbot:Bot = bottypes[idx].Clone(new Point(Math.random() * mapsizex, Math.random() * mapsizey),
Math.random() * 360,
true);
var nameidx:uint = Math.random() * botnames[idx].length;
var newname:String = botnames[idx][nameidx];
botcount++;
newbot.name = newname + "-" + botcount;
botsactive++;
for (var i:uint = 0; i < len; i++) {
if (!bots[i].exist) {
bots[i] = newbot;
return;
}
}
// if we made it this far just add it to the vector
bots.push(newbot);
}
function GenBot():void {
var p:uint = Math.random() * bottotalprob;
var idx:uint = 0;
while (p >= bottypes[idx].prob) {
p -= bottypes[idx].prob;
idx++;
}
GenBotIndex(idx);
}
function GenBullet(bot:Bot, pos:Point, dir:Number, damage:Number, speed:Number, lifespan:uint):void {
bullets.push(new Bullet(bot, pos, dir, damage, speed, lifespan));
}
function NearestBot(no:uint):uint {
var nearestno:int = -1;
var nearestdis:Number;
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (!bots[i].exist)
continue;
if (i != no) {
var dist:Number = Distance(bots[no].pos, bots[i].pos, 10000);
if ((nearestno == -1 || dist < nearestdis) && dist > 0 && bots[i].exist) {
nearestno = i;
nearestdis = dist;
}
}
}
return nearestno;
}
function Distance(p1:Point, p2:Point, maxdis:Number):Number {
var dx:Number = Math.abs(p1.x - p2.x);
var dy:Number = Math.abs(p1.y - p2.y);
if (dx > maxdis) return -1;
if (dy > maxdis) return -1;
if (dx + dy > maxdis * 2) return -1;
return (dx * dx + dy * dy);
}
function MouseClick(evt:MouseEvent):void {
SelectBots(new Point(evt.stageX + curviewpoint.x, evt.stageY + curviewpoint.y));
}
function SelectBots(clickpos:Point):void {
var mindist:Number;
var minno:int = -1;
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (bots[i].exist) {
var dist:Number = Distance(clickpos, bots[i].pos, 20);
if ((minno == -1 || dist < mindist) && dist > 0 && dist <= 256) {
mindist = dist;
minno = i;
}
}
}
if (minno > -1) {
selectedbot = bots[minno];
}
}
function MouseDown(evt:MouseEvent):void {
if (evt.buttonDown) {
mousedownpoint.x = evt.stageX;
mousedownpoint.y = evt.stageY;
}
}
function MouseMove(evt:MouseEvent):void {
if (evt.buttonDown) {
var mouseX:Number = evt.stageX;
var mouseY:Number = evt.stageY;
tempviewpoint.x = viewpoint.x - mouseX + mousedownpoint.x;
tempviewpoint.y = viewpoint.y - mouseY + mousedownpoint.y;
if (tempviewpoint.x < 0 - 200) tempviewpoint.x = 0 - 200;
if (tempviewpoint.y < 0 - 200) tempviewpoint.y = 0 - 200;
if (tempviewpoint.x > mapsizex - 465 + 200) tempviewpoint.x = mapsizex - 465 + 200;
if (tempviewpoint.y > mapsizey - 465 + 200) tempviewpoint.y = mapsizey - 465 + 200;
}
}
function MouseUp(evt:MouseEvent):void {
viewpoint.x = tempviewpoint.x;
viewpoint.y = tempviewpoint.y;
}
function KeyDown(evt:KeyboardEvent):void {
if (evt.charCode == 32) paused = !paused;
if (evt.charCode == 82 || evt.charCode == 114) selectedbot = null;
}
// View point following and updating
function UpdateViewpoint():void {
if (selectedbot != null && selectedbot.exist) {
tempviewpoint.x = selectedbot.pos.x - (465 / 2 - 50);
tempviewpoint.y = selectedbot.pos.y - 465 / 2;
viewpoint.x = curviewpoint.x;
viewpoint.y = curviewpoint.y;
}
// Update view points
curviewpoint.x = 0.92 * curviewpoint.x + 0.08 * tempviewpoint.x;
curviewpoint.y = 0.92 * curviewpoint.y + 0.08 * tempviewpoint.y;
}
function DrawBots():void {
var lbound:Number = curviewpoint.x - 20;
var rbound:Number = curviewpoint.x + 465 + 20;
var tbound:Number = curviewpoint.y - 20;
var bbound:Number = curviewpoint.y + 465 + 20;
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (bots[i].exist) {
var px:Number = bots[i].pos.x;
var py:Number = bots[i].pos.y;
if (px > lbound && px < rbound && py > tbound && py < bbound) DrawBot(bots[i]);
}
}
}
function DrawBot(bot:Bot):void {
var shape:Shape = BotShape(bot);
shape.x = bot.pos.x - curviewpoint.x;
shape.y = bot.pos.y - curviewpoint.y;
shape.rotation = bot.dir;
global.addChild(shape);
}
function BotShape(bot:Bot):Shape {
var _shape:Shape = new Shape();
var strength:Number = 1.3;
_shape.graphics.lineStyle(2, bot.color);
var sp:Point = new Point(0, -12);
var sp2:Point = new Point(-6, 10);
var sp3:Point = new Point(6, 10);
_shape.graphics.moveTo(sp.x, sp.y);
_shape.graphics.lineTo(sp2.x, sp2.y);
_shape.graphics.lineTo(sp3.x, sp3.y);
_shape.graphics.lineTo(sp.x, sp.y);
// highlight Gods/Demigods a bit more
if (bot.type == 1)
strength = 1.9;
_shape.filters = [new GlowFilter(bot.color, 1, 8, 8, strength, 2)];
return _shape;
}
function DrawBullets():void {
var lbound:Number = curviewpoint.x - 20;
var rbound:Number = curviewpoint.x + 465 + 20;
var tbound:Number = curviewpoint.y - 20;
var bbound:Number = curviewpoint.y + 465 + 20;
var len:uint = bullets.length;
for (var i:uint = 0; i < len; i++) {
if (bullets[i].exist) {
var px:Number = bullets[i].pos.x;
var py:Number = bullets[i].pos.y;
if (px > lbound && px < rbound && py > tbound && py < bbound) DrawBullet(bullets[i]);
}
}
}
function DrawBullet(bullet:Bullet):void {
var shape:Shape = BulletShape();
shape.x = bullet.pos.x - curviewpoint.x;
shape.y = bullet.pos.y - curviewpoint.y;
shape.rotation = bullet.dir;
global.addChild(shape);
}
function BulletShape():Shape {
var _shape:Shape = new Shape();
_shape.graphics.beginFill(0x00ffff, 1);
_shape.graphics.drawCircle(0, 0, 2);
_shape.graphics.endFill();
return _shape;
}
function DrawMap():void {
var shape:Shape = MapShape();
shape.x = -curviewpoint.x;
shape.y = -curviewpoint.y;
shape.rotation = 0;
global.addChild(shape);
}
function MapShape():Shape {
var _shape:Shape = new Shape();
_shape.graphics.lineStyle(2, 0x0088BB, 0.7);
_shape.graphics.moveTo(0, 0);
_shape.graphics.lineTo(mapsizex, 0);
_shape.graphics.lineTo(mapsizex, mapsizey);
_shape.graphics.lineTo(0, mapsizey);
_shape.graphics.lineTo(0, 0);
_shape.graphics.lineStyle(1, 0x0088BB, 0.7);
for( var i:uint = 50; i < mapsizex; i+=50) {
_shape.graphics.moveTo(i, 0);
_shape.graphics.lineTo(i, mapsizey);
}
for( var j:uint = 50; j < mapsizey; j+=50) {
_shape.graphics.moveTo(0, j);
_shape.graphics.lineTo(mapsizex, j);
}
return _shape;
}
function DrawMinimap():void {
var shape:Array = MinimapShape();
var shape2:Shape = MiniFOVShape();
shape2.x = 365 + curviewpoint.x / 10;
shape2.y = curviewpoint.y / 10;
global.addChild(shape[0]);
global.addChild(shape[1]);
global.addChild(shape2);
var len:uint = bots.length;
for (var i:uint = 0; i < len; i++) {
if (bots[i].exist) DrawMiniBot(bots[i]);
}
}
function MinimapShape():Array {
var minimapx:Number = mapsizex / 10;
var minimapy:Number = mapsizey / 10;
var shape:Array = [];
var _shape:Shape = new Shape();
_shape.graphics.beginFill(0x0088BB, 0.4);
_shape.graphics.moveTo(365, 0);
_shape.graphics.lineTo(365 + minimapx, 0);
_shape.graphics.lineTo(365 + minimapx, minimapy);
_shape.graphics.lineTo(365, minimapy);
_shape.graphics.lineTo(365, 0);
_shape.graphics.endFill();
var _shape2:Shape = new Shape();
_shape2.graphics.beginFill(0x00001E, 0.4);
_shape2.graphics.moveTo(366 , 1);
_shape2.graphics.lineTo(365 + minimapx - 1, 1);
_shape2.graphics.lineTo(365 + minimapx - 1, minimapy - 1);
_shape2.graphics.lineTo(366, minimapy - 1);
_shape2.graphics.lineTo(366, 1);
_shape2.graphics.endFill();
shape.push(_shape);
shape.push(_shape2);
return shape;
}
function MiniFOVShape():Shape {
var _shape:Shape = new Shape();
_shape.graphics.lineStyle(1, 0x0088BB, 0.5);
_shape.graphics.moveTo(0, 0);
_shape.graphics.lineTo(46.5, 0);
_shape.graphics.lineTo(46.5, 46.5);
_shape.graphics.lineTo(0, 46.5);
_shape.graphics.lineTo(0, 0);
return _shape;
}
function DrawMiniBot(bot:Bot):void {
var shape:Shape = MiniBotShape(bot);
shape.x = 365 + bot.pos.x / 10;
shape.y = bot.pos.y / 10;
global.addChild(shape);
}
function MiniBotShape(bot:Bot):Shape {
var _shape:Shape = new Shape();
_shape.graphics.beginFill(bot.color, 1);
_shape.graphics.drawCircle(0, 0, 1);
_shape.graphics.endFill();
return _shape;
}
function DrawSelectedBot():void {
// Unselect non-exist bot
if (selectedbot != null) {
if (selectedbot.exist) {
var shape:Shape = new Shape();
shape.graphics.lineStyle(2, 0xffffff, 0.5);
shape.graphics.drawCircle(0, 0, 16);
shape.graphics.moveTo(6, -19);
shape.graphics.lineTo(0, -23);
shape.graphics.lineTo(-6, -19);
shape.filters = [new GlowFilter(0xffffff, 1, 8, 8, 3, 2)];
shape.x = selectedbot.pos.x - curviewpoint.x;
shape.y = selectedbot.pos.y - curviewpoint.y;
shape.rotation = selectedbot.dir;
global.addChild(shape);
}
else {
selectedbot = null;
}
}
}
function DrawBotStatus():void {
// Unselect non-exist bot
if (selectedbot != null) {
if (selectedbot.exist) {
var shape:Array = BotStatusShape();
var target:String = "";
global.addChild(shape[0]);
global.addChild(shape[1]);
if (selectedbot.target != null && selectedbot.target.exist)
target = selectedbot.target.name;
stField.text = String(selectedbot.name) + "\n"
+ "\n"
+ "Posx: " + String(getPoint(selectedbot.pos.x, 1)) + "\n"
+ "Posy: " + String(getPoint(selectedbot.pos.y, 1)) + "\n"
+ "Direction: " + String(getPoint(selectedbot.dir, 1)) + "\n"
+ "\n"
+ "HP: " + String(getPoint(selectedbot.hp, 0)) + "/" + String(getPoint(selectedbot.maxhp, 0)) + "\n"
+ "MaxSpeed: " + String(getPoint(selectedbot.speed, 1)) + "\n"
+ "MaxTurn: " + String(getPoint(selectedbot.turn, 1)) + "\n"
+ "ShotSpeed: " + String(getPoint(selectedbot.shotspeed, 1)) + "\n"
+ "BulletDamage: " + String(getPoint(selectedbot.bdamage, 1)) + "\n"
+ "BulletSpeed: " + String(getPoint(selectedbot.bspeed, 1)) + "\n"
+ "BulletLife: " + String(getPoint(selectedbot.blifespan, 1)) + "\n"
+ "BulletDeviation: " + String(getPoint(selectedbot.bdev, 1)) + "\n"
+ "Shield: " + String(getPoint(selectedbot.shield, 1)) + "\n"
+ "Regeneration: " + String(getPoint(selectedbot.regen, 1)) + "\n"
+ "\n"
+ "Kills: " + String(selectedbot.kills) + "\n"
+ "Cash: " + String(selectedbot.cash) + "\n"
+ "\n"
+ "Hate: " + String(selectedbot.targethate) + "\n"
+ target;
global.addChild(stField);
}
else {
selectedbot = null;
}
}
}
function BotStatusShape():Array {
var shape:Array = [];
var _shape:Shape = new Shape();
_shape.graphics.beginFill(0x0088BB, 0.4);
_shape.graphics.moveTo(365, 100);
_shape.graphics.lineTo(365, 465);
_shape.graphics.lineTo(465, 465);
_shape.graphics.lineTo(465, 100);
_shape.graphics.lineTo(365, 100);
_shape.graphics.endFill();
var _shape2:Shape = new Shape();
_shape2.graphics.beginFill(0x00001E, 0.4);
_shape2.graphics.moveTo(366, 101);
_shape2.graphics.lineTo(366, 464);
_shape2.graphics.lineTo(464, 464);
_shape2.graphics.lineTo(464, 101);
_shape2.graphics.lineTo(366, 101);
_shape2.graphics.endFill();
shape.push(_shape);
shape.push(_shape2);
return shape;
}
function DrawTextField():void {
tField.text = "Frames: " + String(ticks)
+ " Bots:" + String(bots.length) + " Bullets:" + String(bullets.length) + "\n"; //Unsort-out bots and bullets
tField.text = tField.text + "mouseX:" + String(global.mouseX) + " mouseY:" + String(global.mouseY)
+ " cFOVx: " + String(int(curviewpoint.x)) + " cFOVy: " + String(int(curviewpoint.y));
global.addChild(tField);
}
function DrawPaused():void {
if (paused) {
var tFormat:TextFormat = new TextFormat;
tFormat.font = "Arial";
tFormat.bold = false;
tFormat.color = 0xffffff;
tFormat.size = 20;
tFormat.align = TextFormatAlign.CENTER;
var textField:TextField = new TextField;
textField.defaultTextFormat = tFormat;
textField.selectable = false;
textField.x = 365;
textField.y = 435;
textField.width = 100;
textField.height = 30;
textField.text = "PAUSED";
textField.filters = [new GlowFilter(0xffffff, 1, 2, 2)];
global.addChild(textField);
}
}
class Bot {
function Bot(_name:String, _pos:Point, _dir:Number,
_maxhp:Number, _type:uint,
_speed:Number, _turn:Number,
_shotspeed:uint,
_bdamage:Number, _bspeed:Number,
_blifespan:uint, _bdev:Number,
_shield:Number, _regen:Number,
_cash:uint, _prob:uint,
_color:uint,
_exist:Boolean = false) {
this.hp = _maxhp;
this.maxhp = _maxhp;
this.type = _type;
this.exist = _exist;
this.name = _name;
if (_pos == null)
this.pos = null;
else
this.pos = new Point(_pos.x, _pos.y);
this.dir = _dir;
this.speed = _speed;
this.turn = _turn;
this.shotspeed = _shotspeed;
this.bdamage = _bdamage;
this.bspeed = _bspeed;
this.blifespan = _blifespan;
this.bdev = _bdev;
this.shield = _shield;
this.regen = _regen;
this.cash = _cash;
this.prob = _prob;
this.color = _color;
this.kills = 0;
this.target = null;
this.targethate = 0;
}
public static function StatInstance(_name:String,
_maxhp:Number, _type:uint,
_speed:Number, _turn:Number,
_shotspeed:uint,
_bdamage:Number, _bspeed:Number,
_blifespan:uint, _bdev:Number,
_shield:Number, _regen:Number,
_prob:uint, _color:uint):Bot {
return new Bot(_name, null, 0, _maxhp, _type, _speed, _turn, _shotspeed, _bdamage, _bspeed, _blifespan, _bdev, _shield, _regen, 0, _prob, _color, false);
}
public function Clone(_point:Point, _dir:uint, _exist:Boolean = false):Bot {
return new Bot(name, _point, _dir, maxhp, type, speed, turn, shotspeed, bdamage, bspeed, blifespan, bdev, shield, regen, cash, prob, color, _exist);
}
public var hp:Number;
public var maxhp:Number;
public var exist:Boolean;
public var name:String; // Unique name
public var color:uint; // Color
public var prob:uint; // Probability that this bot gets generated
public var pos:Point; // Position in Point
public var dir:Number; // Direction in degrees
public var speed:Number; // Move speed in pixels/s
public var turn:Number; // Rotate speed in degrees/s
public var shotspeed:uint;
public var bdamage:Number; // Bullet damage
public var bspeed:Number; // Bullet speed in pixels/s
public var blifespan:uint; // Bullet lifespan in frames
public var bdev:Number; // Bullet direction deviation in degrees
public var shield:Number; // Shield
public var regen:Number; // Regeneration in 1/s
public var kills:uint;
public var cash:uint;
public var type:uint; // Type of bot, determines AI and color
public var target:Bot; // Current AI Target
public var targethate:uint; // Frames of hate for target
public function FaceToPosition(pos:Point):void {
var temp:Number = this.turn;
var theta:Number = Math.atan2(pos.y - this.pos.y, pos.x - this.pos.x);
theta = (theta * 180 / Math.PI - this.dir + 810) % 360;
if (1 <= theta && theta <= 179) {
if (temp > theta) temp = theta;
this.dir = this.dir + temp;
}
else if (181 <= theta && theta <= 359) {
if (temp > 360 - theta) temp = 360 - theta;
this.dir = this.dir - temp;
}
}
public function AddHate(attacker:Bot, amount:uint):void {
if (type == 4)
amount *= 3;
if (attacker == target)
targethate += amount;
else {
if (targethate <= amount)
{
// switch targets
target = attacker;
targethate = 180 + (amount - targethate); // 3 seconds of "hate buffer"
}
else
targethate -= amount;
}
}
}
class Bullet {
function Bullet(_bot:Bot, _pos:Point, _dir:Number,
_damage:Number, _speed:Number, _lifespan:uint,
_lifetime:uint = 0,
_exist:Boolean = true) {
this.damage = _damage;
this.exist = _exist;
this.bot = _bot;
this.pos = new Point(_pos.x, _pos.y);
this.dir = _dir;
this.lifetime = _lifetime;
this.speed = _speed;
this.lifespan = _lifespan;
}
public var damage:Number;
public var exist:Boolean;
public var bot:Bot; // Belongs to which bot
public var pos:Point; // Position in Point
public var dir:Number; // Direction in degrees
public var lifetime:uint; // Lifetime in frames
public var speed:Number; // Move speed in pixels
public var lifespan:uint; // Lifespan in frames
}
function getPoint(num:Number, l:int):Number {
return (Math.round(num * Math.pow(10, l)) / Math.pow(10, l));
}