diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Authors.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Authors.txt new file mode 100644 index 000000000..6287cbe41 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Authors.txt @@ -0,0 +1,11 @@ +Model by pluto +-------------- +Model, texture and animations. + +Sounds by ala +------------- +CC Attribution 3.0 license (http://creativecommons.org/licenses/by/3.0/). + +MooqSnort1-3 +MooqSnorting1-2 + diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/DefCore.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/DefCore.txt new file mode 100644 index 000000000..0479d998b --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/DefCore.txt @@ -0,0 +1,21 @@ +[DefCore] +id=Mooq +Version=7,0,0,0 +Category=C4D_Living +Width=20 +Height=12 +Offset=-10,-6 +Vertices=7 +VertexX= 0, 0,0,-5,5,-5, 5 +VertexY= 0,-5,5, 1,1,-1,-1 +VertexCNAT=0, 4,8, 1,2, 1, 2 +VertexFriction=300,300,100,300,300,300,300 +Mass=250 +ContactCalls=1 +NoGet=1 +Float=0 +BorderBound=1 +StretchGrowth=1 +IncompleteActivity=1 +Oversize=1 +Pathfinder=1 diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Blast.ocd/Graphics.8.png b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Blast.ocd/Graphics.8.png new file mode 100644 index 000000000..a12d35bb2 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Blast.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Blast.ocd/Particle.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Blast.ocd/Particle.txt new file mode 100644 index 000000000..52cb159dc --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Blast.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Blast +Face=0,0,40,40,-20,-20 diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Clusterflight.ocd/Graphics.8.png b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Clusterflight.ocd/Graphics.8.png new file mode 100644 index 000000000..12ca81b38 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Clusterflight.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Clusterflight.ocd/Particle.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Clusterflight.ocd/Particle.txt new file mode 100644 index 000000000..b55cbc39f --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Clusterflight.ocd/Particle.txt @@ -0,0 +1,3 @@ +[Particle] +Name=Clusterflight +Face=0,0,64,64,-32,-32 diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/DefCore.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/DefCore.txt new file mode 100644 index 000000000..aa61e419d --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/DefCore.txt @@ -0,0 +1,13 @@ +[DefCore] +id=Mooq_Firebomb +Version=7,0,0,0 +Category=C4D_Vehicle +Width=5 +Height=5 +Offset=-3,-3 +Value=10 +Mass=10 +Vertices=1 +VertexY=1 +VertexFriction=20 +BorderBound=1 \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Graphics.8.png b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Graphics.8.png new file mode 100644 index 000000000..31f873879 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Graphics.8.png differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Script.c b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Script.c new file mode 100644 index 000000000..1ef3f9de7 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Firebomb.ocd/Script.c @@ -0,0 +1,65 @@ +/*-- Firebomb --*/ + +static const FIREBOMB_DAMAGE = 70; + +func Initialize() { + SetAction("Fly"); +} + +func Hit() { + var dmg = FIREBOMB_DAMAGE; + + BlastObjects(GetX(), GetY(), dmg/2, 0, GetOwner() + 1); + BlastObjects(GetX(), GetY(), dmg/2, 0, GetOwner() + 1); + + var blast = { + R = 255, + G = 255, + B = 255, + Size = (dmg*13)/20, // /10 + Phase = PV_Linear(0, 21), + DampingX = 1000, + DampingY = 1000, + BlitMode = GFX_BLIT_Additive + }; + + CreateParticle("Blast", 0, 0, 0, 0, 21, blast, 1); + + Sound("Blast3"); + RemoveObject(); +} + +func Sparkle() { + if(Contained()) + return false; + + var clusterflight = { + R = 200 + Random(55), + G = 200 + Random(55), + B = 200 + Random(55), + Alpha = PV_Linear(255, 0), //AlphaFade=4 + Size = 16, //40 + Phase = PV_Linear(0, 9), + Rotation = PV_Random(360), + DampingX = 1000, + DampingY = 1000, + //Attach = ATTACH_MoveRelative + }; + + CreateParticle("Clusterflight", 0, 0, RandomX(-2,2),RandomX(-2,2), 36, clusterflight, 1); +} + +/* Act Map */ + +local ActMap = { +Fly = { + Prototype = Action, + Name = "Fly", + Procedure = nil, + Length = 1, + Delay = 1, // 1 + NextAction = "Fly", + FacetBase = 1, + PhaseCall = "Sparkle", +}, +}; diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Graphics.mesh b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Graphics.mesh new file mode 100644 index 000000000..d33c8a3e9 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Graphics.mesh differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Mooq.material b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Mooq.material new file mode 100644 index 000000000..a041db018 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Mooq.material @@ -0,0 +1,21 @@ +material Mooq +{ + receive_shadows on + technique + { + pass + { + ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0 + diffuse 0.6400000190734865 0.6400000190734865 0.6400000190734865 1.0 + specular 0.5 0.5 0.5 1.0 12.5 + emissive 0.0 0.0 0.0 1.0 + + texture_unit + { + texture Mooq.png + tex_address_mode wrap + filtering trilinear + } + } + } +} diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Mooq.png b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Mooq.png new file mode 100644 index 000000000..54a8872c8 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Mooq.png differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort1.wav b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort1.wav new file mode 100644 index 000000000..97a71cddf Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort1.wav differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort2.wav b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort2.wav new file mode 100644 index 000000000..949034ae8 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort2.wav differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort3.wav b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort3.wav new file mode 100644 index 000000000..80fa8478c Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnort3.wav differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnorting1.wav b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnorting1.wav new file mode 100644 index 000000000..72de2bf08 Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnorting1.wav differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnorting2.wav b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnorting2.wav new file mode 100644 index 000000000..5566c950d Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/MooqSnorting2.wav differ diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Script.c b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Script.c new file mode 100644 index 000000000..154e4ed6a --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/Script.c @@ -0,0 +1,817 @@ +/** + Mooq + Author: jok +*/ + +local Name = "$Name$"; +local Description = "$Description$"; + + +// Animations. +local turn_angle; +// Color. +local color; + +// The closest enemy that has been found. +local enemy; +// Closest food that has been found. +local food; + +public func Place(int amount, proplist rectangle, proplist settings) { + var max_tries = 3 * amount; + var loc_area = nil; + if (rectangle) loc_area = Loc_InArea(rectangle); + var animal; + + while ((amount > 0) && (--max_tries > 0)) { + // Try to find walkable ground near lava. + var lava_spot = FindLocation(Loc_Material("DuroLava")); + var ground_spot = nil; + if (lava_spot) { + var lava_rectangle = Shape->Rectangle(lava_spot.x - 200, lava_spot.y - 200, 400, 400); + // Make sure the position is inside the required target rectangle. + lava_rectangle = Shape->Intersect(lava_rectangle, rectangle)->GetBoundingRectangle(); + ground_spot = FindLocation(Loc_Wall(CNAT_Bottom), Loc_Or(Loc_Sky(), Loc_Tunnel()), Loc_Space(20, CNAT_Top), Loc_InArea(lava_rectangle)); + } + + // If no hip and cool spot found, just get some generic spot. + if (!ground_spot) ground_spot = FindLocation(Loc_Wall(CNAT_Bottom), Loc_Or(Loc_Sky(), Loc_Tunnel()), Loc_Space(20, CNAT_Top), loc_area); + if (!ground_spot) continue; + + animal = CreateObjectAbove(this, ground_spot.x, ground_spot.y, NO_OWNER); + if (!animal) continue; + + if (animal->Stuck()) { + animal->RemoveObject(); + continue; + } + --amount; + } + return animal; +} + +public func Construction() { + turn_angle = -60; + color = 255; + + AddEffect("IntActivity", this, 1, 10, this); + AddTimer("UpdateEnemy", 30); + AddTimer("UpdateFood", 60); + + Stop(); + CheckTurn(GetDir()); + + SetTailOnFire(); + + SetCreatureControlled(); + + return true; +} + +public func CatchBlow(int damage, object from) { + Schedule(this, "Sound(\"MooqHurt*\")", RandomX(5, 20)); +} + +/* ActionCallBacks */ + +protected func CheckStuck() { + // Prevents getting stuck on middle vertex + if(!GetXDir()) if(Abs(GetYDir()) < 5) + if(GBackSolid(0, 3)) SetPosition(GetX(), GetY() - 1); +} + +private func ClearActivity() { + this.Activity = nil; +} + +private func StartSwim() { + this.Activity = this.ActivitySwimming; +} + +private func StartWalk() { + SetTailOnFire(); + this.Activity = this.ActivityWalking; +} + +public func Death() { + SoundAt("MooqDie"); +} + +private func SpitPhase() { + if(GetActTime() > 45 && GetActTime() < 65) { + if(!Random(4)) { + var iX, iY; + iX = 5; if (!GetDir()) iX = -iX; + iY = -4; + Smoke(iX,iY,5); + } + } + if(GetActTime() == 58) { + var iX, iY, iXDir, iYDir; + iX = 10; if (!GetDir()) iX = -iX; + iY = -4; + iXDir = 300; if (!GetDir()) iXDir = -iXDir; + iYDir = -300; + + Sound("MooqSpit"); + var obj = CreateContents(Mooq_Firebomb); + obj->Exit(iX, iY); + obj->SetXDir(iXDir,100); + obj->SetYDir(iYDir,100); + } +} + +private func EatPhase() { + var actt = GetActTime(); + if(actt > 13 && actt < 25) { + if(!Random(4)) { + var iX, iY; + iX = 5; if (!GetDir()) iX = -iX; + iY = 4; + Smoke(iX,iY,5); + } + } + if(actt == 22) { + Sound("MooqMunch"); + DoEnergy(food->GetMass()); + food->RemoveObject(); + } + if(actt > 43 && actt < 55) { + if(!Random(4)) { + var iX, iY; + iX = 5; if (!GetDir()) iX = -iX; + iY = 1; + Smoke(iX,iY,5); + } + } +} + +/* Activity */ + +private func ActivitySwimming() { + CheckBreathe(); + if(GetMaterial() == Material("Water")) CheckFossilize(); + + // Stuck? + if (GetComDir() && !GetXDir() && !GetYDir()) { + DoJump(true); + return Swim(Random(2)); + } + + // Fossilizing? + if(GetEffect("IntFossilizing", this)) { + var lava_spot = FindLava(); + if (lava_spot) return TaskSwimTo(lava_spot); + } + + if (enemy) + if (Random(2)) return TaskSwimTo(enemy); + + if (!enemy && food) return TaskSwimTo(food); + + if (!Random(6)) return Swim(Random(2)); + + if (!Random(6)) return DoJump(true); +} + +private func ActivityWalking() { + // Stuck? + if (GetComDir() && !GetXDir() && !GetYDir()) { + if(GetDir()) + Walk(0); + else + Walk(1); + return DoJump(); + } + + // Fossilizing? + if(GetEffect("IntFossilizing", this)) { + var lava_spot = FindLava(); + if (lava_spot) return TaskWalkTo(lava_spot); + } + + // If enemy, hopefully attack! + if (enemy) { + var distance = ObjectDistance(this, enemy); + + if (distance < 50 && Random(2)) return TaskHeadbutt(distance); + + if (Inside(distance, 85, 145) && !Random(5)) return TaskSpit(); + } + + // If no enemy, go to food and eat. + if (!enemy && food) return TaskFood(); + + // If not walking, randomly idle. + if (GetAction() == "Stand") { + if (!enemy && !food) { + // Idle? + if (!Random(15)) return TaskIdle(); + } + + if (!Random(5)) return Walk(Random(2)); + + return; + } + + if (!Random(5)) return Stop(); + + if (!Random(5)) return Walk(Random(2)); + + if (GetAction() == "Walk") { + if (!Random(5)) return DoJump(); + } + + // Anticipate holes in the landscape while walking. + +} + +private func FxIntActivityTimer(target, effect, time) { + if (this.Activity) this->Activity(); + if (!GetAlive()) return -1; + return 1; +} + +private func FxIntActivityDamage(target, effect, dmg) { + if(dmg > 0) return dmg; + return dmg; +} + +/* Tasks */ + +private func TaskIdle() { + Sound("MooqSnorting*"); + if(!Random(3)) return SetAction("IdleSit"); + if(!Random(2)) return SetAction("IdleStand"); + return SetAction("IdleTailwave"); +} + +private func TaskFood() { + var distance = ObjectDistance(this, food); + if (distance < 11) return Eat(); + + return TaskWalkTo(food); +} + +private func TaskHeadbutt(distance) { + if (distance < 11) return Headbutt(); + + return TaskWalkTo(enemy); +} + +private func TaskSpit() { + var eX = enemy->GetX(); + var iX = GetX(); + + if (iX < eX) { + if (GetDir() != DIR_Right) return Turn(DIR_Right); + Stop(); + return Spit(); + } + else { + if (GetDir() != DIR_Left) return Turn(DIR_Left); + Stop(); + return Spit(); + } +} + +private func TaskWalkTo(spot) { + var iX = GetX(); + var iY = GetY(); + + if (GetType(spot) == C4V_C4Object) { + var sX = spot->GetX(); + var sY = spot->GetY(); + } + else if (GetType(spot) == C4V_PropList) { + var sX = spot.x; + var sY = spot.y; + } + else return; + + if (iX < sX) { + if (GetDir() == DIR_Right) + if(iY > sY + 6) + if(Random(2)) if(DoJump()) + return true; + + return Walk(DIR_Right); + } + else { + if (GetDir() == DIR_Left) + if(iY > sY + 6) + if(Random(2)) if(DoJump()) + return true; + return Walk(DIR_Left); + } +} + +private func TaskSwimTo(spot) { + var iX = GetX(); + var iY = GetY(); + + if (GetType(spot) == C4V_C4Object) { + var sX = spot->GetX(); + var sY = spot->GetY(); + } + else if (GetType(spot) == C4V_PropList) { + var sX = spot.x; + var sY = spot.y; + } + else return; + + if (iX < sX) { + if (GetDir() == DIR_Right) + if(iY > sY) + if(DoJump(true)) + return true; + + return Swim(DIR_Right); + } + else { + if (GetDir() == DIR_Left) + if(iY > sY) + if(DoJump(true)) + return true; + return Swim(DIR_Left); + } +} + +/* Actions */ + +private func Stop() { + SetComDir(COMD_Stop); + SetXDir(0); + return SetAction("Stand"); +} + +private func Turn(int dir, bool move) { + if (dir == nil) { + if (GetDir() == DIR_Left) dir = DIR_Right; + else dir = DIR_Left; + } + + if(GetDir() == dir) return; + + return CheckTurn(dir, move); +} + +private func Walk(int dir) { + if (GetAction() != "Stand" && GetAction() != "Walk") return; + + if(GetDir() == dir) { + SetAction("Walk"); + if (GetDir()) return SetComDir(COMD_Right); + else return SetComDir(COMD_Left); + } + + return Turn(dir, true); +} + +private func Swim(int dir) { + if (GetAction() != "Swim") return; + + if(GetDir() == dir) { + SetAction("Swim"); + if (GetDir()) return SetComDir(COMD_UpRight); + else return SetComDir(COMD_UpLeft); + } + + return Turn(dir, true); +} + +private func DoJump(bool swimming) { + if (GetAction() != "Walk" && GetAction() != "Stand" && GetAction() != "Swim") return; + + if (swimming) { + if(GBackSky(0, -2)) SetPosition(GetX(), GetY() - 2 ); + else return; + + var iX, iY, iXDir, iYDir; + iX = 10; if (!GetDir()) iX = -iX; + iY = -4; + iXDir = 200; if (!GetDir()) iXDir = -iXDir; + iYDir = -200; + + if (Random(2)) Sound("MooqSnort*"); + + SetSpeed(iXDir + GetXDir(100), iYDir + GetYDir(100), 100); + return true; + } + if (Random(2)) Sound("MooqSnort*"); + return Jump(); +} + +private func Spit() { + if (GetAction() == "Stand") return SetAction("Spit"); +} + +public func Eat(object food) { + Stop(); + if(GetAction() == "Stand") return SetAction("Eat"); +} + +private func Headbutt() { + if (GetAction() != "Walk") return; + + Punch(enemy, 10); + return SetAction("Headbutt"); +} + +/* FindEnemy */ + +private func UpdateEnemy() { + // Already disposed of the last one? + if (enemy && !enemy->GetAlive()) enemy = nil; + // Last one too far away now? + if (enemy && ObjectDistance(this, enemy) > 250) enemy = nil; + // Slid in water? + if (enemy && enemy->GBackLiquid()) enemy = nil; + + var x = GetX(); + var y = GetY(); + for (var obj in FindObjects(Find_Distance(200), Find_OCF(OCF_Alive), Find_Hostile(GetOwner()), Sort_Distance())) { + if (!PathFree(x, y, obj->GetX(), obj->GetY())) continue; + if (obj->GBackLiquid()) continue; + enemy = obj; + return; + } +} + +/* FindFood */ + +private func UpdateFood() { + // Need food? + if (GetEnergy() >= MaxEnergy/1000) return food = nil; + // Last one too far away now? + if (food && ObjectDistance(this, food) > 150) food = nil; + // Slid in water? + if (food && food->GBackLiquid()) food = nil; + + var x = GetX(); + var y = GetY(); + var Find_FoodIDs = Find_Or(Find_ID(Rock), Find_ID(Coal), Find_ID(Ore)); + for (var obj in FindObjects(Find_Distance(100), Find_FoodIDs, Sort_Distance())) { + if (!PathFree(x, y, obj->GetX(), obj->GetY())) continue; + if (obj->GBackLiquid()) continue; + food = obj; + return; + } +} + +/* FindLava */ + +private func FindLava() { + var lava_spot = FindLocation(Loc_Material("DuroLava"), Loc_Space(20)); + if (lava_spot) return lava_spot; + + var lava_spot = FindLocation(Loc_Material("Lava"), Loc_Space(20)); + if (lava_spot) return lava_spot; + + return; +} + +/* Turning */ + +private func CheckTurn(int dir, bool move) { + if(!GetEffect("IntTurning", this)) { + SetDir(dir); + AddEffect("IntTurning", this, 1, 1, this, nil, move); + return true; + } + return false; +} + +private func FxIntTurningStart(object target, effect fx, temp, move) { + fx.mvmn = move; + + if(!InLiquid()) { + Stop(); + SetAction("Turn"); + } + else { + SetComDir(COMD_Stop); + SetXDir(0); + SetAction("SwimTurn"); + } + + if(temp) return true; +} + +private func FxIntTurningTimer(object target, effect fx, int time) { + if(GetDir() == DIR_Left) turn_angle += 15; + else turn_angle -= 15; + + if(turn_angle < -60 || turn_angle > 180) { + turn_angle = BoundBy(turn_angle, -60, 180); + this.MeshTransformation = Trans_Rotate(turn_angle + 180 + 30,0,1,0); + return -1; + } + this.MeshTransformation = Trans_Rotate(turn_angle + 180 + 30,0,1,0); + return 1; +} + +private func FxIntTurningStop(object target, effect fx, temp) { + if(fx.mvmn) { + if(!InLiquid()) { + if (GetDir()) SetComDir(COMD_Right); + else SetComDir(COMD_Left); + return SetAction("Walk"); + } + + if (GetDir()) SetComDir(COMD_UpRight); + else SetComDir(COMD_UpLeft); + return SetAction("Swim"); + } +} + +/* Breathing */ + +private func CheckBreathe() { + if(!GetEffect("IntBreathing", this)) AddEffect("IntBreathing", this, 1, 1, this, nil); +} + +private func FxIntBreathingStart(object target, effect fx, temp) { + if(temp) return true; +} + +private func FxIntBreathingTimer(object target, effect fx, int time) { + DoBreath(MaxBreath - GetBreath()); + if (!InLiquid()) return -1; + + return 1; +} + +/* Fossilizing */ + +private func CheckFossilize() { + if(!GetEffect("IntFossilizing", this)) + // Ca. 60 seconds till death without lava + AddEffect("IntFossilizing", this, 1, 11, this, nil); +} + +private func FxIntFossilizingStart(object target, effect fx, temp) { + if(temp) return true; +} + +private func FxIntFossilizingTimer(object target, effect fx, int time) { + if(GetMaterial() == Material("DuroLava") || GetMaterial() == Material("Lava")) { + color++; + if(Speed < MaxSpeed) Speed += Random(2); + if(JumpSpeed < MaxJumpSpeed) { + JumpSpeed += Random(3); + if(JumpSpeed > MaxJumpSpeed) JumpSpeed = MaxJumpSpeed; + } + } + else { // if(GetMaterial() == Material("Water")) + color--; + if(Speed > 0) Speed -= Random(2); + if(JumpSpeed > 0) { + JumpSpeed -= Random(3); + if(JumpSpeed < 0) JumpSpeed = 0; + } + } + if(color < 45 || color > 255) { + color = BoundBy(color, 45, 255); + SetClrModulation(RGBa(color, color, color, 255)); + return -1; + } + SetClrModulation(RGBa(color, color, color, 255)); + + return 1; +} + +private func FxIntFossilizingStop(object target, effect fx, temp) { + if(GetMaterial() == Material("DuroLava") || GetMaterial() == Material("Lava")) return SetAction("Swim"); + else return Kill();// if(GetMaterial() == Material("Water")) +} + +/* Burning Tail */ + +private func SetTailOnFire() { + if(!GetEffect("IntTailBurning", this)) { + AddEffect("IntTailBurning", this, 1, 2, this, nil); + } +} + +private func FxIntTailBurningStart(object target, effect fx, temp) { + fx.fire = { + R = 200 + Random(55), + G = 200 + Random(55), + B = 200 + Random(55), + Alpha = PV_Linear(255, 0), + Size = 4, + Phase = PV_Linear(0, 9), + DampingX = 1000, + DampingY = 1000, + Attach = ATTACH_MoveRelative + }; + + if(temp) return true; +} + +private func FxIntTailBurningTimer(object target, effect fx, int time) { + if (!GetAlive() || InLiquid()) { + var level; + level = 5 ?? 10; + var particles = Particles_Smoke(); + particles.Size = PV_Linear(PV_Random(level/2, level), PV_Random(2 * level, 3 * level)); + var pos = [3, -1, 0]; + var dir = [PV_Random(-level/3, level/3), PV_Random(-level/2, -level/3), 0]; + CreateParticleAtBone("Smoke", "tail_3", pos, dir, PV_Random(level * 2, level * 10), particles, BoundBy(level/5, 3, 20)); + return -1; + } + + var pos = [3, -1, 0]; + var dir = [0, 0, 0]; + CreateParticleAtBone("Fire", "tail_3", pos, dir, 5, fx.fire, 1); + return 1; +} + +/* ActMap */ + +local MaxEnergy = 250000; +local MaxBreath = 720; // Mooq can breathe for 20 seconds under water. // But it haz special effects ignoring MaxBreath. +local MaxSpeed = 100; +local Speed = MaxSpeed; +local MaxJumpSpeed = 300; +local JumpSpeed = MaxJumpSpeed; +local NoBurnDecay = 1; + +local ActMap = { +Walk = { + Prototype = Action, + Name = "Walk", + Procedure = DFA_WALK, + Speed = Speed, + Accel = 4, + Decel = 22, + Directions = 2, + FlipDir = 0, + Length = 12, + Delay = 1, + Animation = "Walk", + StartCall = "StartWalk", + InLiquidAction = "Swim", +}, +Swim = { + Prototype = Action, + Name = "Swim", + Procedure = DFA_SWIM, + Speed = Speed, + Accel = 16, + Decel = 22, + Directions = 2, + FlipDir = 0, + Length = 12, + Delay = 1, + Animation = "Swim", + StartCall = "StartSwim", +}, +Jump = { + Prototype = Action, + Name = "Jump", + Procedure = DFA_FLIGHT, + Speed = 200, + Accel = 14, + Directions = 2, + FlipDir = 0, + Length = 20, + Delay = 1, + Animation = "Jump", + NextAction = "Hold", + PhaseCall = "CheckStuck", + StartCall = "ClearActivity", + InLiquidAction = "Swim", +}, +Dead = { + Prototype = Action, + Name = "Dead", + Directions = 2, + FlipDir = 0, + Length = 30, + Delay = 1, + Animation = "Death", + NextAction = "Hold", + StartCall = "ClearActivity", + NoOtherAction = 1, + ObjectDisabled = 1, +}, +Stand = { + Prototype = Action, + Name = "Stand", + Procedure = DFA_WALK, //DFA_THROW + Directions = 2, + FlipDir = 0, + Length = 90, + Delay = 1, + Animation = "Stand", + NextAction = "Stand", + StartCall = "StartWalk", + InLiquidAction = "Swim", +}, +Turn = { + Prototype = Action, + Name = "Turn", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 16, + Delay = 1, + Animation = "Walk", + NextAction = "Stand", + StartCall = "ClearActivity", +}, +SwimTurn = { + Prototype = Action, + Name = "SwimTurn", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 16, + Delay = 1, + Animation = "Swim", + NextAction = "Swim", + StartCall = "ClearActivity", +}, +Spit = { + Prototype = Action, + Name = "Spit", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 90, + Delay = 1, + Animation = "SitMouthOpen", + NextAction = "Stand", + PhaseCall = "SpitPhase", + StartCall = "ClearActivity", + InLiquidAction = "Swim", +}, +Eat = { + Prototype = Action, + Name = "Eat", + Procedure = DFA_NONE, + Directions = 2, + Length = 60, + Delay = 1, + Animation = "Eat", + PhaseCall = "EatPhase", + StartCall = "ClearActivity", + NextAction = "Stand", + InLiquidAction = "Swim", + Attach=CNAT_Bottom, +}, +Headbutt = { + Prototype = Action, + Name = "Headbutt", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 12, + Delay = 1, + Animation = "Headbutt", + StartCall = "ClearActivity", + NextAction = "Stand", + InLiquidAction = "Swim", +}, +IdleStand = { + Prototype = Action, + Name = "IdleStand", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 32, + Delay = 1, + Animation = "IdleStand", + NextAction = "Stand", + InLiquidAction = "Swim", + StartCall = "ClearActivity", +}, +IdleSit = { + Prototype = Action, + Name = "IdleSit", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 64, + Delay = 1, + Animation = "IdleSit", + NextAction = "Stand", + InLiquidAction = "Swim", + StartCall = "ClearActivity", +}, +IdleTailwave = { + Prototype = Action, + Name = "IdleTailwave", + Procedure = DFA_THROW, + Directions = 2, + FlipDir = 0, + Length = 16, + Delay = 1, + Animation = "IdleTailwave", + NextAction = "Stand", + InLiquidAction = "Swim", + StartCall = "ClearActivity", +}, +}; diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/StringTblDE.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/StringTblDE.txt new file mode 100644 index 000000000..95dd751e7 --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/StringTblDE.txt @@ -0,0 +1,2 @@ +Name=Mooq +Description=Süße kleine Kreatur. Mag Lava. \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/StringTblUS.txt b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/StringTblUS.txt new file mode 100644 index 000000000..65ca015bb --- /dev/null +++ b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/StringTblUS.txt @@ -0,0 +1,2 @@ +Name=Mooq +Description=Cute little creature. Likes lava. \ No newline at end of file diff --git a/planet/Objects.ocd/Animals.ocd/Mooq.ocd/mooq.skeleton b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/mooq.skeleton new file mode 100644 index 000000000..080858a3d Binary files /dev/null and b/planet/Objects.ocd/Animals.ocd/Mooq.ocd/mooq.skeleton differ