1 /**
2 Mooq
3 Author: jok
4 */
5
6 // Animations
7 local turn_angle;
8 // Color
9 local color;
10 // The closest enemy that has been found.
11 local enemy;
12 // Closest food that has been found.
13 local food;
14
Place(int amount,proplist rectangle,proplist settings)15 public func Place(int amount, proplist rectangle, proplist settings)
16 {
17 var max_tries = 3 * amount;
18 var loc_area = nil;
19 if (rectangle) loc_area = Loc_InArea(rectangle);
20 var animal;
21
22 while ((amount > 0) && (--max_tries > 0))
23 {
24 // Try to find walkable ground near lava.
25 var lava_spot = FindLocation(Loc_Material("DuroLava"));
26 var ground_spot = nil;
27 if (lava_spot)
28 {
29 var lava_rectangle = Shape->Rectangle(lava_spot.x - 200, lava_spot.y - 200, 400, 400);
30 // Make sure the position is inside the required target rectangle.
31 lava_rectangle = Shape->Intersect(lava_rectangle, rectangle)->GetBoundingRectangle();
32 ground_spot = FindLocation(Loc_Wall(CNAT_Bottom), Loc_Or(Loc_Sky(), Loc_Tunnel()), Loc_Space(20, CNAT_Top), Loc_InArea(lava_rectangle));
33 }
34
35 // If no hip and cool spot found, just get some generic spot.
36 if (!ground_spot) ground_spot = FindLocation(Loc_Wall(CNAT_Bottom), Loc_Or(Loc_Sky(), Loc_Tunnel()), Loc_Space(20, CNAT_Top), loc_area);
37 if (!ground_spot) continue;
38
39 animal = CreateObjectAbove(this, ground_spot.x, ground_spot.y, NO_OWNER);
40 if (!animal) continue;
41
42 if (animal->Stuck())
43 {
44 animal->RemoveObject();
45 continue;
46 }
47 --amount;
48 }
49 return animal;
50 }
51
IsAnimal()52 public func IsAnimal() { return true; }
53
Construction()54 func Construction()
55 {
56 turn_angle = -60;
57 color = 255;
58
59 AddEffect("IntActivity", this, 1, 10, this);
60 AddTimer("UpdateEnemy", 30);
61 AddTimer("UpdateFood", 60);
62
63 Stop();
64 CheckTurn(GetDir());
65
66 SetTailOnFire();
67 }
68
Death()69 func Death()
70 {
71 RemoveTimer("UpdateEnemy");
72 RemoveTimer("UpdateFood");
73 RemoveEffect("IntActivity", this);
74
75 Sound("Animals::Mooq::Die*");
76 }
77
CatchBlow(int damage,object from)78 func CatchBlow(int damage, object from)
79 {
80 Schedule(this, "Sound(\"Animals::Mooq::Hurt*\")", RandomX(5, 20));
81 }
82
83 /* Action Callbacks */
84
CheckStuck()85 func CheckStuck()
86 {
87 // Prevents getting stuck on middle vertex
88 if(!GetXDir())
89 if(Abs(GetYDir()) < 5)
90 if(GBackSolid(0, 3))
91 SetPosition(GetX(), GetY() - 1);
92 }
93
ClearActivity()94 func ClearActivity()
95 {
96 this.Activity = nil;
97 }
98
StartSwim()99 func StartSwim()
100 {
101 this.Activity = this.ActivitySwimming;
102 }
103
StartWalk()104 func StartWalk()
105 {
106 SetTailOnFire();
107 this.Activity = this.ActivityWalking;
108 }
109
SpitPhase()110 func SpitPhase()
111 {
112 if(GetActTime() > 45 && GetActTime() < 65)
113 {
114 if(!Random(4))
115 {
116 var iX, iY;
117 iX = 5;
118 if (!GetDir()) iX = -iX;
119 iY = -4;
120 Smoke(iX,iY,5);
121 }
122 }
123 if(GetActTime() == 58)
124 {
125 var iX, iY, iXDir, iYDir;
126 iX = 10;
127 if (!GetDir()) iX = -iX;
128 iY = -4;
129 iXDir = 300;
130 if (!GetDir()) iXDir = -iXDir;
131 iYDir = -300;
132
133 Sound("Animals::Mooq::Spit*");
134
135 var obj = CreateContents(Mooq_Firebomb);
136 obj->Exit(iX, iY);
137 obj->SetXDir(iXDir,100);
138 obj->SetYDir(iYDir,100);
139 }
140 }
141
EatPhase()142 func EatPhase()
143 {
144 var actt = GetActTime();
145
146 if(actt > 13 && actt < 25)
147 {
148 if(!Random(4))
149 {
150 var iX, iY;
151 iX = 5;
152 if (!GetDir()) iX = -iX;
153 iY = 4;
154 Smoke(iX,iY,5);
155 }
156 }
157 if(actt == 22)
158 {
159 if (!food) return;
160
161 Sound("Animals::Mooq::Munch*");
162 DoEnergy(food->GetMass());
163 food->RemoveObject();
164 }
165 if(actt > 43 && actt < 55)
166 {
167 if(!Random(4))
168 {
169 var iX, iY;
170 iX = 5;
171 if (!GetDir()) iX = -iX;
172 iY = 1;
173 Smoke(iX,iY,5);
174 }
175 }
176 }
177
178 /* Activity */
179
ActivitySwimming()180 func ActivitySwimming()
181 {
182 CheckBreathe();
183 if(GetMaterial() == Material("Water"))
184 CheckFossilize();
185
186 // Stuck?
187 if (GetComDir() && !GetXDir() && !GetYDir())
188 {
189 DoJump(true);
190 return Swim(Random(2));
191 }
192
193 // Fossilizing?
194 if(GetEffect("IntFossilizing", this))
195 {
196 var lava_spot = FindLava();
197 if (lava_spot)
198 return TaskSwimTo(lava_spot);
199 }
200
201 if (enemy && Random(2)) return TaskSwimTo(enemy);
202
203 if (!enemy && food) return TaskSwimTo(food);
204
205 if (!Random(6)) return Swim(Random(2));
206
207 if (!Random(6)) return DoJump(true);
208 }
209
ActivityWalking()210 func ActivityWalking()
211 {
212 // Stuck?
213 if (GetComDir() && !GetXDir() && !GetYDir())
214 {
215 if(GetDir())
216 Walk(0);
217 else
218 Walk(1);
219 return DoJump();
220 }
221
222 // Fossilizing?
223 if(GetEffect("IntFossilizing", this))
224 {
225 var lava_spot = FindLava();
226 if (lava_spot) return TaskWalkTo(lava_spot);
227 }
228
229 // If enemy, hopefully attack!
230 if (enemy)
231 {
232 var distance = ObjectDistance(this, enemy);
233
234 if (distance < 50 && Random(2)) return TaskHeadbutt(distance);
235
236 if (Inside(distance, 85, 145) && !Random(5)) return TaskSpit();
237 }
238
239 // If no enemy, go to food and eat.
240 if (!enemy && food) return TaskFood();
241
242 // If not walking, randomly idle.
243 if (GetAction() == "Stand")
244 {
245 if (!enemy && !food)
246 {
247 // Idle?
248 if (!Random(15)) return TaskIdle();
249 }
250
251 if (!Random(5)) return Walk(Random(2));
252
253 return;
254 }
255
256 if (!Random(5)) return Stop();
257
258 if (!Random(5)) return Walk(Random(2));
259
260 if (GetAction() == "Walk")
261 {
262 if (!Random(5)) return DoJump();
263 }
264
265 // Anticipate holes in the landscape while walking.
266
267 }
268
FxIntActivityTimer(target,effect,time)269 func FxIntActivityTimer(target, effect, time)
270 {
271 if (this.Activity) this->Activity();
272 if (!GetAlive()) return -1;
273 return 1;
274 }
275
FxIntActivityDamage(target,effect,dmg)276 func FxIntActivityDamage(target, effect, dmg)
277 {
278 if (dmg > 0) return dmg;
279 return dmg;
280 }
281
282 /* Tasks */
283
TaskIdle()284 func TaskIdle()
285 {
286 Sound("Animals::Mooq::Snorting*");
287
288 if (!Random(3)) return SetAction("IdleSit");
289 if (!Random(2)) return SetAction("IdleStand");
290
291 return SetAction("IdleTailwave");
292 }
293
TaskFood()294 func TaskFood()
295 {
296 var distance = ObjectDistance(this, food);
297 if (distance < 11) return Eat();
298
299 return TaskWalkTo(food);
300 }
301
TaskHeadbutt(distance)302 func TaskHeadbutt(distance)
303 {
304 if (distance < 11) return Headbutt();
305
306 return TaskWalkTo(enemy);
307 }
308
TaskSpit()309 func TaskSpit()
310 {
311 var eX = enemy->GetX();
312 var iX = GetX();
313
314 if (iX < eX)
315 {
316 if (GetDir() != DIR_Right) return Turn(DIR_Right);
317 Stop();
318 return Spit();
319 } else {
320 if (GetDir() != DIR_Left) return Turn(DIR_Left);
321 Stop();
322 return Spit();
323 }
324 }
325
TaskWalkTo(spot)326 func TaskWalkTo(spot)
327 {
328 var iX = GetX();
329 var iY = GetY();
330
331 if (GetType(spot) == C4V_C4Object)
332 {
333 var sX = spot->GetX();
334 var sY = spot->GetY();
335 }
336 else if (GetType(spot) == C4V_PropList)
337 {
338 var sX = spot.x;
339 var sY = spot.y;
340 }
341 else return;
342
343 if (iX < sX)
344 {
345 if (GetDir() == DIR_Right)
346 if (iY > sY + 6)
347 if (Random(2)) if(DoJump())
348 return true;
349
350 return Walk(DIR_Right);
351 } else {
352 if (GetDir() == DIR_Left)
353 if(iY > sY + 6)
354 if(Random(2)) if(DoJump())
355 return true;
356 return Walk(DIR_Left);
357 }
358 }
359
TaskSwimTo(spot)360 func TaskSwimTo(spot)
361 {
362 var iX = GetX();
363 var iY = GetY();
364
365 if (GetType(spot) == C4V_C4Object)
366 {
367 var sX = spot->GetX();
368 var sY = spot->GetY();
369 }
370 else if (GetType(spot) == C4V_PropList)
371 {
372 var sX = spot.x;
373 var sY = spot.y;
374 }
375 else return;
376
377 if (iX < sX)
378 {
379 if (GetDir() == DIR_Right)
380 if(iY > sY)
381 if(DoJump(true))
382 return true;
383
384 return Swim(DIR_Right);
385 } else {
386 if (GetDir() == DIR_Left)
387 if(iY > sY)
388 if(DoJump(true))
389 return true;
390 return Swim(DIR_Left);
391 }
392 }
393
394 /* Actions */
395
Stop()396 func Stop()
397 {
398 SetComDir(COMD_Stop);
399 SetXDir(0);
400 return SetAction("Stand");
401 }
402
Turn(int dir,bool move)403 func Turn(int dir, bool move)
404 {
405 if (dir == nil)
406 {
407 if (GetDir() == DIR_Left)
408 dir = DIR_Right;
409 else
410 dir = DIR_Left;
411 }
412
413 if(GetDir() == dir) return;
414
415 return CheckTurn(dir, move);
416 }
417
Walk(int dir)418 func Walk(int dir)
419 {
420 if (GetAction() != "Stand" && GetAction() != "Walk") return;
421
422 if (GetDir() == dir)
423 {
424 SetAction("Walk");
425 if (GetDir())
426 return SetComDir(COMD_Right);
427 else
428 return SetComDir(COMD_Left);
429 }
430
431 return Turn(dir, true);
432 }
433
Swim(int dir)434 func Swim(int dir)
435 {
436 if (GetAction() != "Swim") return;
437
438 if (GetDir() == dir)
439 {
440 SetAction("Swim");
441 if (GetDir())
442 return SetComDir(COMD_UpRight);
443 else
444 return SetComDir(COMD_UpLeft);
445 }
446
447 return Turn(dir, true);
448 }
449
DoJump(bool swimming)450 func DoJump(bool swimming)
451 {
452 if (GetAction() != "Walk" && GetAction() != "Stand" && GetAction() != "Swim") return;
453
454 if (swimming)
455 {
456 if (GBackSky(0, -2))
457 SetPosition(GetX(), GetY() - 2);
458 else
459 return;
460
461 var iX, iY, iXDir, iYDir;
462 iX = 10;
463 if (!GetDir()) iX = -iX;
464 iY = -4;
465 iXDir = 200;
466 if (!GetDir()) iXDir = -iXDir;
467 iYDir = -200;
468
469 if (Random(2)) Sound("Animals::Mooq::Snort*");
470
471 SetSpeed(iXDir + GetXDir(100), iYDir + GetYDir(100), 100);
472 return true;
473 }
474
475 if (Random(2)) Sound("Animals::Mooq::Snort*");
476 return Jump();
477 }
478
Spit()479 func Spit()
480 {
481 if (GetAction() == "Stand") return SetAction("Spit");
482 }
483
Eat(object food)484 func Eat(object food)
485 {
486 Stop();
487 if (GetAction() == "Stand") return SetAction("Eat");
488 }
489
Headbutt()490 func Headbutt()
491 {
492 if (GetAction() != "Walk") return;
493
494 Punch(enemy, 10);
495 return SetAction("Headbutt");
496 }
497
498 /* FindEnemy */
499
UpdateEnemy()500 func UpdateEnemy()
501 {
502 // Already disposed of the last one?
503 if (enemy && !enemy->GetAlive()) enemy = nil;
504 // Last one too far away now?
505 if (enemy && ObjectDistance(this, enemy) > 250) enemy = nil;
506 // Slid in water?
507 if (enemy && enemy->GBackLiquid()) enemy = nil;
508
509 var x = GetX();
510 var y = GetY();
511 for (var obj in FindObjects(Find_Distance(200), Find_OCF(OCF_Alive), Find_AnimalHostile(GetOwner()), Sort_Distance()))
512 {
513 if (!PathFree(x, y, obj->GetX(), obj->GetY())) continue;
514 if (obj->GBackLiquid()) continue;
515 enemy = obj;
516 return;
517 }
518 }
519
520 /* FindFood */
521
UpdateFood()522 func UpdateFood()
523 {
524 // Need food?
525 if (GetEnergy() >= MaxEnergy/1000) return food = nil;
526 // Last one too far away now?
527 if (food && ObjectDistance(this, food) > 150) food = nil;
528 // Slid in water?
529 if (food && food->GBackLiquid()) food = nil;
530
531 var x = GetX();
532 var y = GetY();
533 var Find_FoodIDs = Find_Or(Find_ID(Rock), Find_ID(Coal), Find_ID(Ore));
534 for (var obj in FindObjects(Find_Distance(100), Find_FoodIDs, Sort_Distance()))
535 {
536 if (!PathFree(x, y, obj->GetX(), obj->GetY())) continue;
537 if (obj->GBackLiquid()) continue;
538 food = obj;
539 return;
540 }
541 }
542
543 /* FindLava */
544
FindLava()545 func FindLava()
546 {
547 var lava_spot = FindLocation(Loc_Material("DuroLava"), Loc_Space(20));
548 if (lava_spot) return lava_spot;
549
550 var lava_spot = FindLocation(Loc_Material("Lava"), Loc_Space(20));
551 if (lava_spot) return lava_spot;
552
553 return;
554 }
555
556 /* Turning */
557
CheckTurn(int dir,bool move)558 func CheckTurn(int dir, bool move)
559 {
560 if (!GetEffect("IntTurning", this))
561 {
562 SetDir(dir);
563 AddEffect("IntTurning", this, 1, 1, this, nil, move);
564 return true;
565 }
566 return false;
567 }
568
FxIntTurningStart(object target,effect fx,temp,move)569 func FxIntTurningStart(object target, effect fx, temp, move)
570 {
571 fx.mvmn = move;
572
573 if (!InLiquid())
574 {
575 Stop();
576 SetAction("Turn");
577 } else {
578 SetComDir(COMD_Stop);
579 SetXDir(0);
580 SetAction("SwimTurn");
581 }
582
583 if (temp) return true;
584 }
585
FxIntTurningTimer(object target,effect fx,int time)586 func FxIntTurningTimer(object target, effect fx, int time)
587 {
588 if (GetDir() == DIR_Left)
589 turn_angle += 15;
590 else
591 turn_angle -= 15;
592
593 if (turn_angle < -60 || turn_angle > 180)
594 {
595 turn_angle = BoundBy(turn_angle, -60, 180);
596 this.MeshTransformation = Trans_Rotate(turn_angle + 180 + 30,0,1,0);
597 return -1;
598 }
599 this.MeshTransformation = Trans_Rotate(turn_angle + 180 + 30,0,1,0);
600 return 1;
601 }
602
FxIntTurningStop(object target,effect fx,temp)603 func FxIntTurningStop(object target, effect fx, temp)
604 {
605 if (fx.mvmn)
606 {
607 if (!InLiquid())
608 {
609 if (GetDir()) SetComDir(COMD_Right);
610 else SetComDir(COMD_Left);
611 return SetAction("Walk");
612 }
613
614 if (GetDir()) SetComDir(COMD_UpRight);
615 else SetComDir(COMD_UpLeft);
616 return SetAction("Swim");
617 }
618 }
619
620 /* Breathing */
621
CheckBreathe()622 func CheckBreathe()
623 {
624 if (!GetEffect("IntBreathing", this)) AddEffect("IntBreathing", this, 1, 1, this, nil);
625 }
626
FxIntBreathingStart(object target,effect fx,temp)627 func FxIntBreathingStart(object target, effect fx, temp)
628 {
629 if (temp) return true;
630 }
631
FxIntBreathingTimer(object target,effect fx,int time)632 func FxIntBreathingTimer(object target, effect fx, int time)
633 {
634 DoBreath(MaxBreath - GetBreath());
635 if (!InLiquid()) return -1;
636
637 return 1;
638 }
639
640 /* Fossilizing */
641
CheckFossilize()642 func CheckFossilize()
643 {
644 if (!GetEffect("IntFossilizing", this))
645 // Ca. 60 seconds till death without lava
646 AddEffect("IntFossilizing", this, 1, 11, this, nil);
647 }
648
FxIntFossilizingStart(object target,effect fx,temp)649 func FxIntFossilizingStart(object target, effect fx, temp)
650 {
651 if (temp) return true;
652 }
653
FxIntFossilizingTimer(object target,effect fx,int time)654 func FxIntFossilizingTimer(object target, effect fx, int time)
655 {
656 if (GetMaterial() == Material("DuroLava") || GetMaterial() == Material("Lava"))
657 {
658 color++;
659 if (Speed < MaxSpeed) Speed += Random(2);
660 if (JumpSpeed < MaxJumpSpeed)
661 {
662 JumpSpeed += Random(3);
663 if(JumpSpeed > MaxJumpSpeed) JumpSpeed = MaxJumpSpeed;
664 }
665 } else {
666 color--;
667 if (Speed > 0) Speed -= Random(2);
668 if (JumpSpeed > 0)
669 {
670 JumpSpeed -= Random(3);
671 if(JumpSpeed < 0) JumpSpeed = 0;
672 }
673 }
674 if (color < 45 || color > 255)
675 {
676 color = BoundBy(color, 45, 255);
677 SetClrModulation(RGBa(color, color, color, 255));
678 return -1;
679 }
680 SetClrModulation(RGBa(color, color, color, 255));
681
682 return 1;
683 }
684
FxIntFossilizingStop(object target,effect fx,temp)685 func FxIntFossilizingStop(object target, effect fx, temp)
686 {
687 if (GetMaterial() == Material("DuroLava") || GetMaterial() == Material("Lava")) return SetAction("Swim");
688 else return Kill();
689 }
690
691 /* Burning Tail */
692
SetTailOnFire()693 func SetTailOnFire()
694 {
695 if (!GetEffect("IntTailBurning", this))
696 AddEffect("IntTailBurning", this, 1, 2, this, nil);
697 }
698
FxIntTailBurningStart(object target,effect fx,temp)699 func FxIntTailBurningStart(object target, effect fx, temp)
700 {
701 fx.fire = {
702 R = 200 + Random(55),
703 G = 200 + Random(55),
704 B = 200 + Random(55),
705 Alpha = PV_Linear(255, 0),
706 Size = 4,
707 Phase = PV_Linear(0, 9),
708 DampingX = 1000,
709 DampingY = 1000,
710 Attach = ATTACH_MoveRelative
711 };
712
713 if (temp) return true;
714 }
715
FxIntTailBurningTimer(object target,effect fx,int time)716 func FxIntTailBurningTimer(object target, effect fx, int time)
717 {
718 if (!GetAlive() || InLiquid())
719 {
720 var level;
721 level = 5 ?? 10;
722 var particles = Particles_Smoke();
723 particles.Size = PV_Linear(PV_Random(level/2, level), PV_Random(2 * level, 3 * level));
724 var pos = [3, -1, 0];
725 var dir = [PV_Random(-level/3, level/3), PV_Random(-level/2, -level/3), 0];
726 CreateParticleAtBone("Smoke", "tail_3", pos, dir, PV_Random(level * 2, level * 10), particles, BoundBy(level/5, 3, 20));
727 return -1;
728 }
729
730 var pos = [3, -1, 0];
731 var dir = [0, 0, 0];
732 CreateParticleAtBone("Fire", "tail_3", pos, dir, 5, fx.fire, 1);
733 return 1;
734 }
735
736 /* ActMap */
737
738 local ActMap = {
739
740 Walk = {
741 Prototype = Action,
742 Name = "Walk",
743 Procedure = DFA_WALK,
744 Speed = Speed,
745 Accel = 4,
746 Decel = 22,
747 Directions = 2,
748 FlipDir = 0,
749 Length = 12,
750 Delay = 1,
751 Animation = "Walk",
752 StartCall = "StartWalk",
753 InLiquidAction = "Swim",
754 },
755 Swim = {
756 Prototype = Action,
757 Name = "Swim",
758 Procedure = DFA_SWIM,
759 Speed = Speed,
760 Accel = 16,
761 Decel = 22,
762 Directions = 2,
763 FlipDir = 0,
764 Length = 12,
765 Delay = 1,
766 Animation = "Swim",
767 StartCall = "StartSwim",
768 },
769 Jump = {
770 Prototype = Action,
771 Name = "Jump",
772 Procedure = DFA_FLIGHT,
773 Speed = 200,
774 Accel = 14,
775 Directions = 2,
776 FlipDir = 0,
777 Length = 20,
778 Delay = 1,
779 Animation = "Jump",
780 NextAction = "Hold",
781 PhaseCall = "CheckStuck",
782 StartCall = "ClearActivity",
783 InLiquidAction = "Swim",
784 },
785 Dead = {
786 Prototype = Action,
787 Name = "Dead",
788 Directions = 2,
789 FlipDir = 0,
790 Length = 30,
791 Delay = 1,
792 Animation = "Death",
793 NextAction = "Hold",
794 StartCall = "ClearActivity",
795 NoOtherAction = 1,
796 ObjectDisabled = 1,
797 },
798 Stand = {
799 Prototype = Action,
800 Name = "Stand",
801 Procedure = DFA_WALK, //DFA_THROW
802 Directions = 2,
803 FlipDir = 0,
804 Length = 90,
805 Delay = 1,
806 Animation = "Stand",
807 NextAction = "Stand",
808 StartCall = "StartWalk",
809 InLiquidAction = "Swim",
810 },
811 Turn = {
812 Prototype = Action,
813 Name = "Turn",
814 Procedure = DFA_THROW,
815 Directions = 2,
816 FlipDir = 0,
817 Length = 16,
818 Delay = 1,
819 Animation = "Walk",
820 NextAction = "Stand",
821 StartCall = "ClearActivity",
822 },
823 SwimTurn = {
824 Prototype = Action,
825 Name = "SwimTurn",
826 Procedure = DFA_THROW,
827 Directions = 2,
828 FlipDir = 0,
829 Length = 16,
830 Delay = 1,
831 Animation = "Swim",
832 NextAction = "Swim",
833 StartCall = "ClearActivity",
834 },
835 Spit = {
836 Prototype = Action,
837 Name = "Spit",
838 Procedure = DFA_THROW,
839 Directions = 2,
840 FlipDir = 0,
841 Length = 90,
842 Delay = 1,
843 Animation = "SitMouthOpen",
844 NextAction = "Stand",
845 PhaseCall = "SpitPhase",
846 StartCall = "ClearActivity",
847 InLiquidAction = "Swim",
848 },
849 Eat = {
850 Prototype = Action,
851 Name = "Eat",
852 Procedure = DFA_NONE,
853 Directions = 2,
854 Length = 60,
855 Delay = 1,
856 Animation = "Eat",
857 PhaseCall = "EatPhase",
858 StartCall = "ClearActivity",
859 NextAction = "Stand",
860 InLiquidAction = "Swim",
861 Attach=CNAT_Bottom,
862 },
863 Headbutt = {
864 Prototype = Action,
865 Name = "Headbutt",
866 Procedure = DFA_THROW,
867 Directions = 2,
868 FlipDir = 0,
869 Length = 12,
870 Delay = 1,
871 Animation = "Headbutt",
872 StartCall = "ClearActivity",
873 NextAction = "Stand",
874 InLiquidAction = "Swim",
875 },
876 IdleStand = {
877 Prototype = Action,
878 Name = "IdleStand",
879 Procedure = DFA_THROW,
880 Directions = 2,
881 FlipDir = 0,
882 Length = 32,
883 Delay = 1,
884 Animation = "IdleStand",
885 NextAction = "Stand",
886 InLiquidAction = "Swim",
887 StartCall = "ClearActivity",
888 },
889 IdleSit = {
890 Prototype = Action,
891 Name = "IdleSit",
892 Procedure = DFA_THROW,
893 Directions = 2,
894 FlipDir = 0,
895 Length = 64,
896 Delay = 1,
897 Animation = "IdleSit",
898 NextAction = "Stand",
899 InLiquidAction = "Swim",
900 StartCall = "ClearActivity",
901 },
902 IdleTailwave = {
903 Prototype = Action,
904 Name = "IdleTailwave",
905 Procedure = DFA_THROW,
906 Directions = 2,
907 FlipDir = 0,
908 Length = 16,
909 Delay = 1,
910 Animation = "IdleTailwave",
911 NextAction = "Stand",
912 InLiquidAction = "Swim",
913 StartCall = "ClearActivity",
914 },
915 };
916
917 local Name = "$Name$";
918 local Description = "$Description$";
919 local MaxEnergy = 250000;
920 local MaxBreath = 720; // Mooq can breathe for 20 seconds under water. // But it haz special effects ignoring MaxBreath.
921 local MaxSpeed = 100;
922 local Speed = MaxSpeed;
923 local MaxJumpSpeed = 300;
924 local JumpSpeed = MaxJumpSpeed;
925 local NoBurnDecay = true;
926 local BorderBound = C4D_Border_Sides;
927 local ContactCalls = true;
928
Definition(proplist def)929 public func Definition(proplist def)
930 {
931 def.PictureTransformation = Trans_Mul(Trans_Translate(2000, 3000, 0), Trans_Scale(1400), Trans_Rotate(20, 1, 0, 0), Trans_Rotate(60, 0, 1, 0));
932 }