PageSourceSearch

https://ra2html5.surge.sh/JS/Game_object/MoviableUnit/Flyable_Unit.js

js ra2html5.surge.sh collected 2026-10-03 14:57:09 UTC 43,824 bytes, 1,254 lines download raw bytes

1/// <reference path="MoviableUnit.js" />
2"use strict";
3
4class Flyable_Unit extends Movealbe_unit {
5
6}
7
8Flyable_Unit.list_unit = [];
9
10
11PIXI.loader.add({ name: "plane", url: "IMG/Unit/Plane/img.json" });
12
13var PLANE_UNIT = {
14    image_type: ["normal", "direct"],
15
16    init_plus: function (property, listresource) {
17        for (var i in property.img) {
18            if (PLANE_UNIT.image_type.indexOf(i) > -1) {
19                IMAGE_PROCESS.process_gl(property.img[i], property.img.main_path, property.img.margin, listresource);
20            }
21        };
22
23
24        if (property.img.shadow) {
25            var path = property.img.main_path.replace("IMG/Unit/Plane/", "");
26            console.log(path + property.img.shadow);
27            property.img.shadowsprite = listresource[0][path + property.img.shadow];
28            console.log(property.img.shadowsprite);
29        }
30    },
31
32    load_texture_done: function (loader, resources) {
33        var listresource = [];
34        listresource[0] = resources.plane.textures;
35        console.log(resources);
36        IMAGE_PROCESS.processcolor_gl(
37            resources.plane_image.texture,
38            TEAM,
39            PLANE_UNIT.process_color_gl_done,
40            listresource
41        );
42    },
43
44    process_color_gl_done: function (textures, listresource) {
45        var baseresource = listresource[0];
46        for (var i = 1 ; i < textures.length; i++) {
47            var processresource = {};
48            var baseTexture = textures[i].baseTexture;
49            for (var j in baseresource) {
50                processresource[j] = new PIXI.Texture(baseTexture, baseresource[j].frame, baseresource[j].crop, baseresource[j].trim);
51            }
52            listresource[i] = processresource;
53        }
54
55        for (var i in PLANE_UNIT_TYPE)
56            PLANE_UNIT.init_plus(PLANE_UNIT_TYPE[i], listresource);
57        console.log(listresource);
58        on_texture_load_done("plane");
59        PLANE_UNIT = null;
60    },
61}
62
63
64
65class Plane_unit extends Flyable_Unit {
66    constructor(x, y, z, team, property) {
67        super(Math.round(x), Math.round(y), z, team, property);
68        this.v = property.property.speed;
69        this.attackdone = property.property.attack_time;
70        this.attackload = this.attackdone;
71        //this.height = 0;
72        this.angel = 0;
73        this.angelv = property.property.angel_v;
74        this.group = null;
75        this.enemy = null;
76        this.goal = null;
77        this.zv = 0;
78
79        if (property.img.high_res) {
80            this.sprite = IMAGE_PROCESS.getsprite_rotate_high(this.property.img.normal.sprites[this.team], this.property.img.normal.margin, 0.85);
81        } else {
82            this.sprite = IMAGE_PROCESS.getsprite_rotate(this.property.img.normal.sprites[this.team], this.property.img.normal.margin, 0.85);
83        }
84        this.shadowsprite = IMAGE_PROCESS.getsprite_shadow(this.property.img.shadowsprite);
85        this.shadowsprite.scale.x *= 0.85;
86        this.shadowsprite.scale.y *= 0.85;
87
88        this.healthsprite = IMAGE_PROCESS.gethealthsprite(this);
89        this.renderable = true;
90        this.height_fly = property.property.height_fly || 22;
91        this.check_collision = true;
92
93    }
94
95
96
97    init() {
98        super.init();
99        stage.addChild(this.sprite);
100        stage.addChild(this.shadowsprite);
101        Flyable_Unit.list_unit.push(this);
102    }
103
104    delete () {
105        stage.removeChild(this.sprite);
106        stage.removeChild(this.shadowsprite);
107        healthcontainer.removeChild(this.healthsprite);
108        Flyable_Unit.list_unit.splice(Flyable_Unit.list_unit.indexOf(this), 1);
109        super.delete();
110    }
111
112
113    draw() {
114        var pos = convert2screen(this.x, this.y, this.z);
115        this.pos = pos;
116        if (check_available_screen(this.pos, this.sprite.width / 2, this.sprite.height / 2) && GRID.check_availble_user_fogmap(this)) {
117            this.angel_idx = get_frame_idx(this.angel, this.sprite.sprites.length - 1);
118            this.sprite.z_idx = this.x + this.y + 0.55;
119            this.sprite.change_rotation(this.angel);
120            this.sprite.position.set(this.pos.x, this.pos.y);
121            this.sprite.renderable = true;
122            if (this.healthsprite) {
123                this.healthsprite.renderable = true;
124                this.healthsprite.position.set(pos.x - 23, pos.y - 30);
125            }
126        } else {
127            this.sprite.renderable = false;
128            if (this.healthsprite) {
129                this.healthsprite.renderable = false;
130                this.healthsprite.position.set(pos.x - 23, pos.y - 30);
131            }
132        }
133
134        var pos_shadow = convert2screen(this.x, this.y, GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)]);
135
136
137        if (check_available_screen(pos_shadow, this.shadowsprite.width / 2, this.shadowsprite.height / 2) && GRID.check_availble_user_fogmap(this)) {
138            this.shadowsprite.position.set(pos_shadow.x, pos_shadow.y);
139            this.shadowsprite.renderable = true;
140            this.shadowsprite.change_rotation(this.angel);
141        } else {
142            this.shadowsprite.renderable = false;
143        }
144    }
145
146    process(time) {
147        this.process_move(time);
148    }
149
150
151    process_move(time) {
152        time /= 60;
153        if (this.goal) {
154            var d = calcfar(this.goal, this);
155            var dnx = (this.goal.x - this.x) / d;
156            var dny = (this.goal.y - this.y) / d;
157            var total_x = 0;
158            let total_y = 0;
159            if (this.check_collision) {
160                for(let e of Flyable_Unit.list_unit) if (e != this) {
161                    let dd = calcfar2(this, e) + 0.01;
162                    let weight = 0.5 * Math.pow(2.5 / dd, 3);
163                    total_x += (e.x - this.x) * weight;
164                    total_y += (e.y - this.y) * weight;
165                }
166            }
167            dnx -= total_x;
168            dny -= total_y;
169
170            var angle = myAtan(dny, dnx);
171            var delta = normal_angel(angle - this.angel);
172            var back_x = this.x;
173            var back_y = this.y;
174
175            this.angel = normal_angel(this.angel + Math.max(-time * this.angelv, Math.min(time * this.angelv, delta)));
176
177
178            this.x += myCos(this.angel) * this.v * time;
179            this.y += mySin(this.angel) * this.v * time;
180            this.z += ((GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)] + this.height_fly - this.z > 0 ? 1 : -1)) * this.v * time * 2;
181
182            if (Math.round(back_x) != Math.round(this.x) || Math.round(back_y) != Math.round(this.y)) {
183                GRID.setmovefogmap(this, Math.round(back_x), Math.round(back_y), Math.round(this.x), Math.round(this.y));
184            }
185
186        }
187    }
188
189
190    /** @description Apply command for list game unit.
191     * @param {Command} command The list of game unit.
192     */
193    command(command) {
194        if (this.state == STATE.DELETE)
195            return;
196        super.command(command);
197        this.next_command = command.next_command;
198
199        this._is_protect_area_ = false;
200        this.group_protect = null;
201        this._go_into_ = false;
202        this._go_into_ob_ = null;
203
204        switch (command.com) {
205            case "protect_area":
206                if (command.group) {
207                    this._is_protect_area_ = true;
208                    this.group_protect = command.group;
209                    if (!this.group_protect._time_) {
210                        this.group_protect._time_ = performance.now();
211                        this.group_protect.listgoal = [];
212                    }
213                }
214                break;
215            case "auto":
216                this._auto_command_ = true;
217                break;
218            case "move":
219                if (command.group) {
220                    this.goal = command.goal;
221                    this.changetostate(STATE.MOVE);
222                }
223                break;
224            case "attack":
225                if (command.group) {
226                    this.enemy = command.enemy;
227                    this.goal = command.enemy;
228                    this.changetostate(STATE.MOVE2ATTACK);
229                }
230                break;
231        }
232    }
233
234
235    on_destroy(attackobject) {
236        super.on_destroy(attackobject);
237        if (Math.random() < 0.5) {
238            GAME_OBJECT.add_effect(this.x, this.y, this.z, EFFECT_TYPE.exploit5);
239        } else {
240            GAME_OBJECT.add_instance(new Plane_unit_failout(this));
241        }
242    }
243
244    on_attacked(attackobject) {
245        super.on_attacked(attackobject);
246        this.healthsprite.sethealth(this.health / this.totalhealth);
247    }
248
249
250    check_choose(x, y) {
251        return this.pos && Math.abs(this.pos.x - x) <= 30 && Math.abs(this.pos.y - y - 3) <= 15;
252    }
253
254    get_element_ceil() {
255        return [];
256    }
257
258    scan_enemy() {
259        return null;
260    }
261
262    filter_enemy() {
263        return false;
264    }
265
266    set_data(array, idx, team) {
267        Movealbe_unit.prototype.set_data.call(this, array, idx, team);
268    }
269
270
271    get_data(team) {
272        return Movealbe_unit.prototype.get_data.call(this, team);
273    }
274
275
276}
277
278
279class Plane_unit_failout extends Game_unit {
280    /**
281     *   @param {Plane_unit} ob
282     * */
283    constructor(ob) {
284        super(ob.x, ob.y, ob.z, -1, ob.property);
285        this.v = ob.v;;
286        this.angel = ob.angel;
287        this.sprite = ob.sprite;
288        this.shadowsprite = ob.shadowsprite;
289        this.original_angel = this.angel;
290        this.angel_rotate = (Math.random() - 0.5) * this.property.img.angel_rotate_fail
291        this.zv = 0;
292        this.sprite.tint = 0x999999;
293        this.wait_smooke = 0;
294    }
295    process(time) {
296        this.wait_smooke += time;
297        time /= 60;
298        this.zv += time * GRAVITY * 0.8;
299        this.x += myCos(this.original_angel) * this.v * time;
300        this.y += mySin(this.original_angel) * this.v * time;
301        this.z -= this.zv * time;
302        this.angel = normal_angel(this.angel_rotate * time + this.angel);
303
304
305        if (this.wait_smooke > 3) {
306            this.wait_smooke = 0;
307            GAME_OBJECT.add_instance(new SmokeEffect2(
308                this.x + Math.random() * 0.3 - 0.15 + 0.7 * myCos(this.angel),
309                this.y + Math.random() * 0.3 - 0.15 + 0.7 * mySin(this.angel),
310                this.z + Math.random() - 0.5,
311                0, 0, 0, 0.6
312                ));
313        } else {
314            GAME_OBJECT.add_instance(new SmokeEffect2_supersort(
315               this.x + 0.7 * myCos(this.angel),
316               this.y + 0.7 * mySin(this.angel),
317               this.z,
318               0, 0, 0, 0.6
319               ));
320        }
321        if (this.z <= GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)]) {
322            GAME_OBJECT.add_effect(this.x, this.y, this.z, EFFECT_TYPE.exploit5);
323            this.delete();
324        }
325
326    }
327    draw() {
328        Plane_unit.prototype.draw.call(this);
329    }
330    delete () {
331        stage.removeChild(this.sprite);
332        stage.removeChild(this.shadowsprite);
333        this.state = STATE.DELETE;
334    }
335    init() {
336        stage.addChild(this.sprite);
337        stage.addChild(this.shadowsprite);
338    }
339}
340
341
342GAME_OBJECT.add_class(Plane_unit, "plane");
343
344
345class Parachutist extends Flyable_Unit {
346
347
348    static init_texture(listresource) {
349        this.textures = [];
350        this.speed = 1 / 3;
351        for (var i = 0 ; i < listresource.length; i++) {
352            this.textures[i] = [];
353            for (var j = 1; j <= 69; j++) {
354                this.textures[i].push(listresource[i][`Drop/drop (${j}).png`]);
355            }
356        }
357        this.shadow_texture = new PIXI.Texture.fromImage("IMG/effect/hidecircle.png");
358    }
359
360
361    constructor(x, y, z, team, property) {
362        super(x, y, z, team, property);
363        this.healthsprite = IMAGE_PROCESS.gethealthsprite(this);
364        this.solider_sprite = IMAGE_PROCESS.getsprites(SOLIDER_TYPE.sol_gi_allied.img.drop.sprites[this.team]);
365        this.speed = Parachutist.speed;
366        this.frame_idx = 0;
367    }
368
369    init() {
370        super.init();
371        stage.addChild(this.solider_sprite);
372        GAME_OBJECT.add_instance(new Parachutist_Sprite(this));
373    }
374
375    delete () {
376        super.delete();
377        healthcontainer.removeChild(this.healthsprite);
378        stage.removeChild(this.solider_sprite);
379    }
380
381
382    draw() {
383        let pos = convert2screen(this.x, this.y, this.z);
384        this.pos = pos;
385        if (check_available_screen(pos, this.solider_sprite.width, this.solider_sprite.height) && GRID.check_availble_user_fogmap(this)) {
386            this.healthsprite.position.set(pos.x - 10, pos.y - 25);
387            this.solider_sprite.position.set(pos.x, pos.y);
388            this.solider_sprite.z_idx = this.x + this.y;
389            this.healthsprite.renderable = true;
390            this.solider_sprite.renderable = true;
391        } else if (this.solider_sprite.renderable) {
392            this.healthsprite.renderable = false;
393            this.solider_sprite.renderable = false;
394
395        }
396    }
397
398    process(time) {
399        super.process(time);
400        if (this.z > GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)]) {
401            var frame = Math.floor(this.timelife * this.speed);
402            this.frame_idx = frame;
403            if (frame < 14) {
404                this.z -= 0.2 * time;
405            } else {
406                this.z -= 0.05 * time;
407            }
408        } else {
409            var newunit = new SOLIDER_TYPE.sol_gi_allied.class(
410                this.x, this.y, this.z, this.team,
411                SOLIDER_TYPE.sol_gi_allied
412            );
413            this.change_type(SOLIDER_TYPE.sol_gi_allied.class, newunit);
414        }
415    }
416
417    /**
418     * @param {Function} type
419     * @param {Game_unit} newinstance
420     * */
421    change_type(type, newinstance) {
422        var command = this._command_;
423        super.change_type(type, newinstance);
424        command && this.command(command);
425    }
426
427
428    /** @description Apply command for list game unit.
429     * @param {Command} command The list of game unit.
430     */
431    command(com) {
432        this._command_ = com;
433    }
434
435
436
437    on_destroy(attackobject) {
438        GAME_OBJECT.add_effect(this.x, this.y, this.z, EFFECT_TYPE.exploit5);
439        super.on_destroy(attackobject);
440    }
441
442    on_attacked(attackobject) {
443        super.on_attacked(attackobject);
444        this.healthsprite.sethealth(this.health / this.totalhealth);
445    }
446
447    display_health_point(onoff) {
448        if (this.state == STATE.DELETE)
449            return;
450        if (onoff)
451            healthcontainer.addChild(this.healthsprite);
452        else
453            healthcontainer.removeChild(this.healthsprite);
454    }
455
456    check_choose(x, y) {
457        return this.pos && Math.abs(this.pos.x - x) <= 30 && Math.abs(this.pos.y - y - 3) <= 15;
458    }
459
460
461
462    get_element_ceil() {
463        return [];
464    }
465
466    scan_enemy() {
467        return null;
468    }
469
470    filter_enemy() {
471        return false;
472    }
473}
474
475
476
477
478class V3Rocket extends Flyable_Unit {
479    constructor(x, y, z, team, property, enemy) {
480        super(Math.round(x), Math.round(y), z, team, property);
481        this.v = property.property.min_v * get_random(0.2);
482        this.acceleration = property.property.acceleration * get_random(0.2);
483        this.angelacceleration = property.property.angelacceleration * get_random(0.2);
484        this.max_v = property.property.max_v * get_random(0.2);
485        this.angel = myAtan(enemy.y - this.y, enemy.x - this.x) + (Math.random() - 0.5) * 0.5;
486        this.angel_h = property.property.angel_h_init;
487        this.sprite = IMAGE_PROCESS.getsprite_rotate_high(
488            this.property.img.normal.sprites[this.team],
489            this.property.img.normal.margin,
490            property.property.scale);
491        this.shadowsprite = IMAGE_PROCESS.getsprite_shadow(this.property.img.shadowsprite);
492        this.shadowsprite.scale.x *= property.property.scale;
493        this.shadowsprite.scale.y *= property.property.scale;
494        this.renderable = true;
495        this.property.sight = 0;
496        this.enemy = enemy;
497        this.vx = 0;
498        this.vy = 0;
499        this.vz = 0;
500        this.wait_smooke = 0;
501    }
502
503
504
505    init() {
506        super.init();
507        stage.addChild(this.sprite);
508        stage.addChild(this.shadowsprite);
509    }
510
511    delete () {
512        stage.removeChild(this.sprite);
513        stage.removeChild(this.shadowsprite);
514        super.delete();
515    }
516
517
518    draw() {
519        if (this.state == STATE.DELETE)
520            return;
521        var pos = convert2screen(this.x, this.y, this.z);
522
523        this.pos = pos;
524        if (check_available_screen(this.pos, this.sprite.width / 2, this.sprite.height / 2) && GRID.check_availble_user_fogmap(this)) {
525
526            // #region CORE CONVERT TO SCREEN
527            var dx = 30 * (-this.vx + this.vy);
528            var dy = -15 * this.vx - 15 * this.vy + 6 * this.vz;
529            var dz = 30 * (-this.vx + -this.vy);
530            var angle1 = myAtan(dy, dx);
531            var angel2 = normal_angel(3 * Math.PI / 4 + myAtan(dz, Math.sqrt(dx * dx + dy * dy)));
532            // #endregion
533
534            this.sprite.z_idx = this.x + this.y + 0.55;
535            this.sprite.change_rotation(angel2);
536            this.sprite.position.set(this.pos.x, this.pos.y);
537            this.sprite.renderable = true;
538            this.sprite.rotation = angle1;
539            if (this.healthsprite) {
540                this.healthsprite.renderable = true;
541                this.healthsprite.position.set(pos.x - 23, pos.y - 30);
542            }
543        } else {
544            this.sprite.renderable = false;
545            if (this.healthsprite) {
546                this.healthsprite.renderable = false;
547                this.healthsprite.position.set(pos.x - 23, pos.y - 30);
548            }
549        }
550
551        var pos_shadow = convert2screen(this.x, this.y, GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)]);
552
553        if (check_available_screen(pos_shadow, this.shadowsprite.width / 2, this.shadowsprite.height / 2) && GRID.check_availble_user_fogmap(this)) {
554            this.shadowsprite.position.set(pos_shadow.x, pos_shadow.y);
555            this.shadowsprite.renderable = true;
556            this.shadowsprite.change_rotation(this.angel);
557        } else {
558            this.shadowsprite.renderable = false;
559        }
560    }
561
562    process(time) {
563        super.process(time);
564        this.process_move(time);
565        var add_speed_smooke = 1;
566
567        if (this.timelife < 30)
568            add_speed_smooke += 1 - (this.timelife / 30);
569
570        this.wait_smooke += time;
571        if (this.wait_smooke >= 2 || this.timelife < 15) {
572            this.wait_smooke = 0;
573            GAME_OBJECT.add_instance(new SmokeEffect2(
574                this.x + Math.random() * 0.2 - 0.1 - 0.7 * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
575                this.y + Math.random() * 0.2 - 0.1 - 0.7 * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
576                this.z + Math.random() * 0.10 - 0.5 - 5 * 0.7 * mySin(this.angel_h),
577                add_speed_smooke * (this.v - this.max_v) * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
578                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
579                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel_h) * 5
580                ));
581        } else {
582            GAME_OBJECT.add_instance(new SmokeEffect2_supersort(
583                this.x - 0.7 * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
584                this.y - 0.7 * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
585                this.z - 5 * 0.7 * mySin(this.angel_h),
586                add_speed_smooke * (this.v - this.max_v) * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
587                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
588                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel_h) * 5
589                ));
590        }
591        if ((GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)] >= this.z)) {
592            this.delete();
593            var x = Math.round(this.x),
594                y = Math.round(this.y);
595            GAME_OBJECT.add_instance(new Weapon(this, { x, y }, ATTACK_TYPE.attack_bomb_explorer));
596        }
597    }
598
599
600    process_move(time) {
601        time /= 60;
602        if (this.enemy) {
603            var DX = this.enemy.x - this.x;
604            var DY = this.enemy.y - this.y;
605            var DZ = (this.enemy.z - this.z) / 5;
606            var DXY = Math.sqrt(DX * DX + DY * DY);
607            var DXYZ = Math.sqrt(DX * DX + DY * DY + DZ * DZ);
608
609            var max_angel_v = this.angelacceleration * time;
610            var angel = myAtan(DY, DX);
611            var angel_h = myAtan(DZ, Math.sqrt(DX * DX + DY * DY));
612            var height = GRID.heightmap[GRID.dim * Math.round(this.x) + Math.round(this.y)];
613
614            this.angel += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel - this.angel)));
615
616            if (DXY < 10 * Math.abs(DZ * 0.18)) {
617                this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel_h - this.angel_h)));
618            }else if(this.z - height < 25){
619                this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(Math.PI / 4 - this.angel_h)));
620            } else {
621                this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(0 - this.angel_h)));
622            }
623
624
625            if (DXYZ > 2 && this.timelife > 90) {
626                this.angel += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel - this.angel)));
627                if (this.angel_h > 0 || DXY < 10 * Math.abs(DZ * 0.18))
628                    this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel_h - this.angel_h)));
629            }
630
631            var h = Math.abs(myCos(this.angel_h));
632            this.v = Math.min(this.max_v, this.v + this.acceleration * time);
633            this.x += this.vx = this.v * myCos(this.angel) * Math.abs(myCos(this.angel_h)) * time;
634            this.y += this.vy = this.v * mySin(this.angel) * Math.abs(myCos(this.angel_h)) * time;
635            this.z += this.vz = this.v * mySin(this.angel_h) * time * 5;
636
637        }
638    }
639
640
641    /** @description Apply command for list game unit.
642     * @param {Command} command The list of game unit.
643     */
644    command(command) { }
645
646
647    on_destroy(attackobject) {
648        super.on_destroy(attackobject);
649        GAME_OBJECT.add_effect(this.x, this.y, this.z, EFFECT_TYPE.exploit5);
650    }
651
652    on_attacked(attackobject) {
653        super.on_attacked(attackobject);
654        console.log(this.health);
655    }
656
657
658    check_choose(x, y) { return false; }
659
660    get_element_ceil() { return []; }
661
662    scan_enemy() { return null; }
663
664    filter_enemy() { return false; }
665}
666
667
668
669
670class Rocker extends Flyable_Unit {
671    constructor(x, y, z, team, property, enemy) {
672        super(Math.round(x), Math.round(y), z, team, property);
673        this.v = property.property.min_v * get_random(0.2);
674        this.acceleration = property.property.acceleration * get_random(0.2);
675        this.angelacceleration = property.property.angelacceleration * get_random(0.2);
676        this.max_v = property.property.max_v * get_random(0.2);
677        this.angel = myAtan(enemy.y - this.y, enemy.x - this.x) + (Math.random() - 0.5) * 0.5;
678        this.angel_h = property.property.angel_h_init;
679        this.sprite = IMAGE_PROCESS.getsprite_rotate_high(
680            this.property.img.normal.sprites[this.team],
681            this.property.img.normal.margin,
682            property.property.scale);
683        this.shadowsprite = IMAGE_PROCESS.getsprite_shadow(this.property.img.shadowsprite);
684        this.shadowsprite.scale.x *= property.property.scale;
685        this.shadowsprite.scale.y *= property.property.scale;
686        this.renderable = true;
687        this.property.sight = 0;
688        this.enemy = enemy;
689        this.vx = 0;
690        this.vy = 0;
691        this.vz = 0;
692        this.wait_smooke = 0;
693    }
694
695
696
697    init() {
698        super.init();
699        stage.addChild(this.sprite);
700        stage.addChild(this.shadowsprite);
701    }
702
703    delete () {
704        stage.removeChild(this.sprite);
705        stage.removeChild(this.shadowsprite);
706        super.delete();
707    }
708
709
710    draw() {
711        if (this.state == STATE.DELETE)
712            return;
713        var pos = convert2screen(this.x, this.y, this.z);
714
715        this.pos = pos;
716        if (check_available_screen(this.pos, this.sprite.width / 2, this.sprite.height / 2) && GRID.check_availble_user_fogmap(this)) {
717
718            // #region CORE CONVERT TO SCREEN
719            var dx = 30 * (-this.vx + this.vy);
720            var dy = -15 * this.vx - 15 * this.vy + 6 * this.vz;
721            var dz = 30 * (-this.vx + -this.vy);
722            var angle1 = myAtan(dy, dx);
723            var angel2 = normal_angel(3 * Math.PI / 4 + myAtan(dz, Math.sqrt(dx * dx + dy * dy)));
724            // #endregion
725
726            this.sprite.z_idx = this.x + this.y + 0.55;
727            this.sprite.change_rotation(angel2);
728            this.sprite.position.set(this.pos.x, this.pos.y);
729            this.sprite.renderable = true;
730            this.sprite.rotation = angle1;
731            if (this.healthsprite) {
732                this.healthsprite.renderable = true;
733                this.healthsprite.position.set(pos.x - 23, pos.y - 30);
734            }
735        } else {
736            this.sprite.renderable = false;
737            if (this.healthsprite) {
738                this.healthsprite.renderable = false;
739                this.healthsprite.position.set(pos.x - 23, pos.y - 30);
740            }
741        }
742
743        var pos_shadow = convert2screen(this.x, this.y, GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)]);
744
745        if (check_available_screen(pos_shadow, this.shadowsprite.width / 2, this.shadowsprite.height / 2) && GRID.check_availble_user_fogmap(this)) {
746            this.shadowsprite.position.set(pos_shadow.x, pos_shadow.y);
747            this.shadowsprite.renderable = true;
748            this.shadowsprite.change_rotation(this.angel);
749        } else {
750            this.shadowsprite.renderable = false;
751        }
752    }
753
754    process(time) {
755        super.process(time);
756        this.process_move(time);
757        var add_speed_smooke = 1;
758
759        if (this.timelife < 30)
760            add_speed_smooke += 1 - (this.timelife / 30);
761
762        this.wait_smooke += time;
763        if (this.wait_smooke >= 2 || this.timelife < 15) {
764            this.wait_smooke = 0;
765            GAME_OBJECT.add_instance(new SmokeEffect2(
766                this.x + Math.random() * 0.2 - 0.1 - 0.7 * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
767                this.y + Math.random() * 0.2 - 0.1 - 0.7 * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
768                this.z + Math.random() * 0.10 - 0.5 - 5 * 0.7 * mySin(this.angel_h),
769                add_speed_smooke * (this.v - this.max_v) * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
770                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
771                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel_h) * 5
772                ));
773        } else {
774            GAME_OBJECT.add_instance(new SmokeEffect2_supersort(
775                this.x - 0.7 * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
776                this.y - 0.7 * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
777                this.z - 5 * 0.7 * mySin(this.angel_h),
778                add_speed_smooke * (this.v - this.max_v) * myCos(this.angel) * Math.abs(myCos(this.angel_h)),
779                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel) * Math.abs(myCos(this.angel_h)),
780                add_speed_smooke * (this.v - this.max_v) * mySin(this.angel_h) * 5
781                ));
782        }
783        if ((GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)] >= this.z)) {
784            this.delete();
785            var x = Math.round(this.x),
786                y = Math.round(this.y);
787            GAME_OBJECT.add_instance(new Weapon(this, { x, y }, ATTACK_TYPE.attack_bomb_explorer));
788        }
789    }
790
791
792    process_move(time) {
793        time /= 60;
794        if (this.enemy) {
795            var DX = this.enemy.x - this.x;
796            var DY = this.enemy.y - this.y;
797            var DZ = (this.enemy.z - this.z) / 5;
798            var DXY = Math.sqrt(DX * DX + DY * DY);
799            var DXYZ = Math.sqrt(DX * DX + DY * DY + DZ * DZ);
800
801            var max_angel_v = this.angelacceleration * time;
802            var angel = myAtan(DY, DX);
803            var angel_h = myAtan(DZ, Math.sqrt(DX * DX + DY * DY));
804            var height = GRID.heightmap[GRID.dim * Math.round(this.x) + Math.round(this.y)];
805
806            this.angel += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel - this.angel)));
807
808            if (DXY < 10 * Math.abs(DZ * 0.18)) {
809                this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel_h - this.angel_h)));
810            } else if (this.z - height < 25) {
811                this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(Math.PI / 4 - this.angel_h)));
812            } else {
813                this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(0 - this.angel_h)));
814            }
815
816
817            if (DXYZ > 2 && this.timelife > 90) {
818                this.angel += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel - this.angel)));
819                if (this.angel_h > 0 || DXY < 10 * Math.abs(DZ * 0.18))
820                    this.angel_h += Math.max(-max_angel_v, Math.min(max_angel_v, normal_angel(angel_h - this.angel_h)));
821            }
822
823            var h = Math.abs(myCos(this.angel_h));
824            this.v = Math.min(this.max_v, this.v + this.acceleration * time);
825            this.x += this.vx = this.v * myCos(this.angel) * Math.abs(myCos(this.angel_h)) * time;
826            this.y += this.vy = this.v * mySin(this.angel) * Math.abs(myCos(this.angel_h)) * time;
827            this.z += this.vz = this.v * mySin(this.angel_h) * time * 5;
828
829        }
830    }
831
832
833    /** @description Apply command for list game unit.
834     * @param {Command} command The list of game unit.
835     */
836    command(command) { }
837
838
839    on_destroy(attackobject) {
840        super.on_destroy(attackobject);
841        GAME_OBJECT.add_effect(this.x, this.y, this.z, EFFECT_TYPE.exploit5);
842    }
843
844    on_attacked(attackobject) {
845        super.on_attacked(attackobject);
846        console.log(this.health);
847    }
848
849
850    check_choose(x, y) { return false; }
851
852    get_element_ceil() { return []; }
853
854    scan_enemy() { return null; }
855
856    filter_enemy() { return false; }
857}
858
859
860var PLANE_UNIT_TYPE = {};
861
862
863var __beag__map__state__ = {
864    "move_to_attack": STATE.MOVE2ATTACK,
865    "return_to_attack": STATE.MOVE2ATTACK,
866    "move": STATE.MOVE,
867    "move_to_home": STATE.MOVE,
868    "attack": STATE.MOVE2ATTACK,
869    "in_home": STATE.IDLE,
870    "take_down": STATE.MOVE
871}
872
873
874PLANE_UNIT_TYPE.beag = {
875    name: "beag",
876    type: "plane",
877    img: {
878        main_path: "IMG/Unit/Plane/beag/",
879        normal: { path: "img", from: 1, to: 19 },
880        shadow: "shadow.png",
881        high_res: true,
882        angel_rotate_fail: 7,
883    },
884    audio: {},
885    property: {
886        shield: { _1: Infinity, _2: 30, _3: 30, _4: 30 },
887        life: 40,
888        cost: 2000,
889        speed: 5.5,
890        attack_type: "attack_tesla",
891        attack_time: 70,
892        attack_dam: 17,
893        range: 13,
894        sight: 14,
895        angel_v: 2,
896        height_fly: 35,
897
898    },
899    //require: ["con_power_allied", "con_tech_allied"],
900    class: class extends Plane_unit {
901        constructor(...Args) {
902            super(...Args);
903            this.state_plus = "in_home";
904            this.bomb_count = 8;
905            this.home = null;
906            this.attacking = false;
907        }
908        init() {
909            super.init();
910            this.healthsprite.set_contain(8, 8);
911        }
912        process(time) {
913            super.process(time);
914            const sss = 13;
915            const attack_delta = 6;
916            switch (this.state_plus) {
917                case "move":
918                    var farfar = calcfar(this, this.goal);
919                    if (farfar < sss * 0.5)
920                        this.changetostateplus("move_to_home");
921                    break;
922                case "move_to_attack":
923                case "return_to_attack":
924                    var angle = myAtan(this.enemy.y - this.y, this.enemy.x - this.x);
925                    var delta = normal_angel(angle - this.angel);
926                    var farfar = calcfar(this, this.enemy);
927                    if (this.state_plus == "move_to_attack") {
928                        this.check_collision = farfar > sss * 1.5;
929                    }
930                    if (this.bomb_count <= 0) {
931                        this.changetostateplus("move_to_home");
932                    } else if (calcfar(this, this.enemy) < sss && Math.abs(Math.tan(delta) * farfar) < 1.1) {
933                        this.changetostateplus("attack");
934                    }
935                    break;
936                case "attack":
937                    if (this.bomb_count > 0) {
938                        this.attackload += time;
939                        let angle = myAtan(this.enemy.y - this.y, this.enemy.x - this.x);
940                        let delta = normal_angel(angle - this.angel);
941
942                        if (this.attackload > attack_delta
943                            && ATTACK_TYPE.attack_bomb_beag.check_can_drop_bomb(this, this.enemy, 2.0)) {
944                            //this.attacking = true;
945                            this.bomb_count--;
946                            this.attackload = 0;
947                            this.attack();
948                            this.healthsprite.set_contain(this.bomb_count, 8);
949                        } else if (this.attacking) {
950                            //this.attacking = false;
951                            //this.check_collision = true;
952                        }
953
954                        if (this.enemy.state == STATE.DELETE) {
955                            this.changetostateplus("move_to_home");
956                        } else if (calcfar(this, this.enemy) > sss * 1.2)
957                            this.changetostateplus("move_to_attack");
958
959
960                    } else {
961                        this.changetostateplus("move_to_home");
962                    }
963                    break;
964                case "move_to_home":
965                    if (!this.home || this.home.state == STATE.DELETE) {
966                        var point = this.find_home();
967                        if (point) {
968                            this.home = point.ob;
969                            this.goal = point.point;
970                        }
971                    }
972                    if (this.home) {
973                        var far = calcfar(this, this.goal);
974                        if (far < 6) {
975                            this.v = this.property.property.speed * Math.sqrt(far / 6);
976                            this.check_collision = false;
977                        }
978                        if (far < 0.1) {
979                            this.changetostateplus("take_down");
980                        }
981                    }
982                    break;
983                case "take_down":
984                    if (this.z > GRID.heightmap[Math.round(this.x) * GRID.dim + Math.round(this.y)]) {
985                        this.z -= time * 0.2;
986                        if (this.home.state == STATE.DELETE)
987                            this.changetostateplus("move_to_home");
988                    } else {
989                        this.changetostateplus("in_home");
990                    }
991                    break;
992                case "in_home":
993                    if (this.home && this.home.health > 0) {
994                        this.bomb_count = Math.min(8, this.bomb_count + time * 0.008);
995                        this.healthsprite.set_contain(Math.floor(this.bomb_count), 8);
996                        this.health = Math.min(this.totalhealth, this.health + time * 0.3);
997                    }
998                    break;
999
1000            }
1001        }
1002        changetostateplus(state) {
1003            this.state_plus = state;
1004            this.check_collision = true;
1005            this.angelv = this.property.property.angel_v;
1006            this.v = this.property.property.speed;
1007            switch (state) {
1008                case "move_to_attack":
1009                case "return_to_attack":
1010                    this.home && this.home.unregister_home(this);
1011                    this.home = null;
1012                    break;
1013                case "move":
1014                    this.home && this.home.unregister_home(this);
1015                    this.home = null;
1016                    this.enemy = null;
1017                    break;
1018                case "move_to_home":
1019                    this.enemy = null;
1020                    break;
1021                case "attack":
1022                    this.home && this.home.unregister_home(this);
1023                    this.check_collision = false;
1024                    this.angelv = 0;
1025                    break;
1026                case "in_home":
1027                    this.goal = false;
1028                    this.enemy = false;
1029                    break;
1030                case "take_down":
1031                    this.check_collision = false;
1032                    this.goal.x += 1;
1033                    this.v = 0;
1034                    break;
1035            }
1036        }
1037        changetostate(state) {
1038            super.changetostate(state);
1039            switch (this.state) {
1040                case STATE.MOVE2ATTACK:
1041                    this.changetostateplus("move_to_attack");
1042                    break;
1043                case STATE.MOVE:
1044                    this.changetostateplus("move");
1045                    break;
1046            }
1047        }
1048        attack() {
1049            GAME_OBJECT.add_instance(new Weapon(this, this.enemy, ATTACK_TYPE.attack_bomb_beag));
1050        }
1051        find_home() {
1052            var list_check = GAME_OBJECT.listgameunit[this.team]
1053                .filter(e => e instanceof CONSTRUCTION_TYPE.con_airplan_allied.class && e.team == this.team);
1054            list_check.forEach(e => e.__far_temp__ = calcfar(this, e));
1055            list_check.sort((e, f) => e.__far_temp__ - f.__far_temp__);
1056
1057            for(var ob of list_check) {
1058                var point = ob.register_home(this);
1059                if (point)
1060                    return { ob, point };
1061            }
1062        }
1063        set_data(array, idx, team) {
1064            var add = (team == this.team);
1065            super.set_data(array, idx, team)
1066            array[idx + 18] = add && this.bomb_count;
1067            array[idx + 9] = add && __beag__map__state__[this.state_plus];
1068        }
1069        get_data(team) {
1070            super.get_data(team);
1071            if (this.team == team) {
1072                this._data_.container = this.bomb_count;
1073                this._data_.state = __beag__map__state__[this.state_plus];
1074            }
1075            return this._data_;
1076        }
1077    }
1078
1079}
1080
1081
1082PLANE_UNIT_TYPE.plane = {
1083    name: "plane",
1084    type: "plane",
1085    img: {
1086        main_path: "IMG/Unit/Plane/plane/",
1087        normal: { path: "img", from: 1, to: 51 },
1088        shadow: "shadow.png",
1089        high_res: true,
1090        angel_rotate_fail: 6,
1091    },
1092    audio: {},
1093    property: {
1094        shield: { _1: Infinity, _2: 100, _3: 100, _4: 100 },
1095        life: 80,
1096        speed: 4.5,
1097        attack_type: "attack_tesla",
1098        attack_time: 70,
1099        attack_dam: 10,
1100        range: 13,
1101        sight: 14,
1102        angel_v: 0.8,
1103        height_fly: 32,
1104    },
1105    require: ["notfound"],
1106
1107    class: class extends Plane_unit {
1108        constructor(x, y, z, team, property) {
1109            super(0, 0, 0, team, property);
1110            this.drop_point = { x, y };
1111            this.stateplus = "init";
1112            this.pa_number = 20;
1113        }
1114        process(time) {
1115            switch (this.stateplus) {
1116                case "init":
1117                    TEAM[this.team].team.send_command([this], {
1118                        com: "move",
1119                        goal: this.drop_point,
1120                        __flag__private__: true
1121                    })
1122                    this.stateplus = "go_to_drop";
1123                    break;
1124                case "go_to_drop":
1125                    if (calcfar(this, this.drop_point) < 6) {
1126                        this.stateplus = "dropping";
1127                        this.angelv = 0;
1128                    }
1129                    break;
1130                case "dropping":
1131                    if (this.pa_number > 0) {
1132                        if (Math.random() < (time * 0.15 * SPEED)) {
1133                            this.pa_number--;
1134                            GAME_OBJECT.add_instance(new Parachutist(
1135                                this.x + 4 * Math.random() - 2,
1136                                this.y + 4 * Math.random() - 2,
1137                                this.z,
1138                                this.team,
1139                                SOLIDER_TYPE.sol_gi_allied
1140                            ));
1141                        }
1142                    } else {
1143                        this.stateplus = "go_back";
1144                        this.angelv = this.property.property.angel_v;
1145                        TEAM[this.team].team.send_command([this], {
1146                            com: "move",
1147                            goal: { x: GRID.dim, y: GRID.dim },
1148                            __flag__private__: true
1149                        });
1150                    }
1151                    break;
1152                case "go_back":
1153                    {
1154                        let x = (this.x - this.y + GRID.dim1_2) / 2;
1155                        let y = (this.x + this.y - GRID.dim1_2) / 2;
1156                        if (x < -10 || y < -10 || x > GRID.dim1_2 + 10 || y > GRID.dim1_2 + 10)
1157                            this.delete();
1158                    }
1159                    break;
1160            }
1161            super.process(time);
1162        }
1163
1164        command(command) {
1165            if (command.__flag__private__) {
1166                super.command(command);
1167            }
1168        }
1169
1170        check_choose(x, y) {
1171            return false;
1172        }
1173    }
1174
1175}
1176
1177
1178PLANE_UNIT_TYPE.zeg = {
1179    name: "zeg",
1180    type: "plane",
1181    img: {
1182        main_path: "IMG/Unit/Plane/zeg/",
1183        normal: { path: "img", from: 1, to: 51 },
1184        shadow: "shadow.png",
1185        angel_rotate_fail: 1.5,
1186    },
1187    audio: {},
1188    property: {
1189        shield: { _1: Infinity, _2: 100, _3: 100, _4: 100 },
1190        life: 800,
1191        cost: 2000,
1192        speed: 0.75,
1193        attack_type: "attack_tesla",
1194        attack_time: 70,
1195        attack_dam: 10,
1196        range: 13,
1197        sight: 14,
1198        angel_v: 0.17,
1199        height_fly: 28
1200    },
1201    require: ["con_power_allied"],
1202    class: Plane_unit
1203}
1204
1205
1206PLANE_UNIT_TYPE.rocket = {
1207    name: "rocket",
1208    type: "plane",
1209    img: {
1210        main_path: "IMG/Unit/Plane/rocket/",
1211        normal: { path: "img", from: 1, to: 40 },
1212        shadow: "shadow.png",
1213    },
1214    audio: {},
1215    property: {
1216        shield: { _1: Infinity, _2: 15, _3: 15, _4: 15 },
1217        life: 100,
1218        angelacceleration: 0.5,
1219        acceleration: 1,
1220        min_v: 0,
1221        max_v: 8.5,
1222        attack_dam: 16,
1223        angel_h_init: Math.PI / 7,
1224        scale : 0.85
1225
1226    },
1227    require: ["Notfound@@@@@@@@"],
1228    class: V3Rocket,
1229    get_object(x, y, z, t, enemy) {
1230        if (!enemy)
1231            throw new Error("sssssssssssssssssssssssss");
1232        return new V3Rocket(x, y, z, t, this, enemy);
1233    }
1234}
1235
1236
1237
1238
1239var ADDITIONAL_TYPE = {};
1240
1241
1242
1243
1244ADDITIONAL_TYPE.parachutist_plane = {
1245    name: "parachutist_plane",
1246    type: "additional",
1247    property: {
1248        time: 120,
1249    },
1250    require: ["cuairp"],
1251    run(team, pos) {
1252        GAME_OBJECT.add_unit(pos.x, pos.y, 0, team, PLANE_UNIT_TYPE.plane);
1253    }
1254};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.