func FindTarget(fx) { // Attack doors and statue unless an enemy clonk is closer than these objectives var objective; if (g_doorleft && GetX()<=g_doorleft ->GetX()+5) objective = g_doorleft; else if (g_doorright && GetX()>=g_doorright->GetX()-5) objective = g_doorright; else objective = g_statue; var target = inherited(fx, ...); if (objective) if (fx.is_siege || !target || ObjectDistance(target) > ObjectDistance(objective)) target = objective; return target; }
global func FireBreathDamage(proplist fx, int angle, int max_reach, int x, int y) { var reach = Min(fx.spray_cur.reach, max_reach * CYCLOPS_FireBreath_Precision); var dx = +Sin(angle, reach) / CYCLOPS_FireBreath_Precision; var dy = -Cos(angle, reach) / CYCLOPS_FireBreath_Precision; if (false) { if (!fx.rock) fx.rock = CreateObject(Rock); fx.rock->SetPosition(x + dx, y + dy); fx.rock->SetXDir(); fx.rock->SetYDir(); } // damage the clonk reach /= CYCLOPS_FireBreath_Precision; reach += 5; // the fuzzy part of the flames if (ObjectDistance(fx.cyclops, fx.target) < reach) { if (cyclops_dangerous) { var damage=1000; fx.target->DoEnergy(-damage, true, FX_Call_EngGetPunched, NO_OWNER); } else { fx.target.hurt_by_cyclops = true; } } }
global func FxIntCyclopsAITimer(object cyclops, proplist fx, int time) { if (!fx.cyclops) { fx.cyclops = cyclops; fx.weapon = cyclops->FindContents(Club); } if (!fx.eye) fx.eye = FindObject(Find_ID(CyclopsEye)); fx.time = time; // do not idle var effect = GetEffect("IntWalk", fx.cyclops); if (effect) effect.idle_time = 0; fx.eye->SetPosition(fx.cyclops->GetX() -4 + fx.cyclops->GetDir() * 8, fx.cyclops->GetY() - 19); // Find an enemy if (fx.target) if (!fx.target->GetAlive() || (!fx.ranged && ObjectDistance(fx.target) >= fx.max_aggro_distance)) fx.target = nil; if (!fx.target) { if (!(fx.target = CyclopsFindTarget(fx))) return CyclopsExecuteIdle(fx); } // Attack it! return CyclopsExecuteMelee(fx, time); }
func CatchBlow(int iLevel, object pObj) { if (GetCategory(pObj) & C4D_Object && GetOCF(pObj) & OCF_Collectible && ObjectDistance(pObj)*10 < 8*Sqrt(GetDefWidth(GetID())*GetDefHeight(GetID())) ) { pObj->~Hit(); // Reduces object speed by 90% if (pObj) { pObj->SetXDir(GetXDir()*5, 0, 100); pObj->SetYDir(GetYDir()*5, 0, 100); } } return _inherited(iLevel, pObj); }
func FxComebackTimer(object target, proplist effect, int time) { if(!this) return; if(!shooter) return RemoveObject(); if(ObjectDistance(this, shooter) < Size) return RemoveObject(); var angle = Angle(GetX(), GetY(), shooter->GetX(), shooter->GetY(), 10); SetVelocity(angle, Speed + 40, 10); }
func Timer() { if(pBeamer && GetCursor(GetOwner()) != this()) return RemoveObject(); Frame++; if(Frame > 10) { Frame = 0; if(GetAction() eq "1") { SetAction("2"); } else { SetAction("1"); } } /*if(GetR() < 360) { SetR(GetR() + 1); } else { SetR(0); }*/ if(ObjectDistance(pBeamer) > LandscapeWidth() / 2 && !FindObject(ENRG)) { if(GetX() > GetX(pBeamer)) { SetXDir(-30); } else { SetXDir(30); } if(GetY() > GetY(pBeamer)) { SetYDir(-30); } else { SetYDir(30); } } SetRDir(3); }
public func Activate(oCaller, oClonk) { if(!oClonk) oClonk = oCaller; // Effekt prüfen var iChkEff; if (iChkEff = CheckEffect("ExtinguishPSpell", oExtiObj, 180)) return(iChkEff!=-1 && RemoveObject()); // Lavafässer zu Granit werden lassen var obj; if (obj = FindContents(LBRL, oClonk)) if (!CheckEffect("ExtinguishPSpell", obj, 180)) { var mat = "Granite"; // Granit nicht geladen -> Stein casten if (!MaterialLoaded(Material(mat))) mat = "Rock"; // Stein nicht geladen -> Kohle casten if (!MaterialLoaded(Material(mat))) mat = "Coal"; // Material schleudern var amount = Min(400, obj->GetAmount()*3); CastPXS(mat, amount, 40, AbsX(GetX(oClonk)), AbsY(GetY(oClonk))); // Objekt entfernen RemoveObject(obj); } // Nächstes brennendes Objekt finden var oExtiObj, iExtiCount; // Den Clonk selbst? if(OnFire(oClonk)) iExtiCount += DoExtinguish(oClonk, oCaller); // Nächstliegende Objekte SetPosition(GetX(oCaller), GetY(oCaller)); // Suchradius ist abhängig von Höhe des Aufrufenden - ein Zauberturm hat einen größeren Radius var iSearchRadius = GetObjHeight(oCaller) * 3; while(oExtiObj = FindObject(0, 0, 0, -1, -1, 0, 0, 0, 0, oExtiObj)) if(ObjectDistance(oCaller, oExtiObj) > iSearchRadius) break; else if(OnFire(oExtiObj)) iExtiCount += DoExtinguish(oExtiObj, oCaller); else if (oExtiObj->~MagicExtinguish(oCaller)) iExtiCount += DoExtinguish(oExtiObj, oCaller); // Irgendwas gelöscht? if (!iExtiCount) return(0, Message("$NoExtinguish$", oClonk), RemoveObject()); // Einmaliger Effekt pro Zauber Sound("Splash1"); return(true); }
bool kexWorldObject::RangeDamage(const char *damageDef, const float dmgRadius, const kexVec3 &dmgOrigin) { if(areaLink.node) { float dist; kexSDNodeObj<kexWorldObject> *areaNode = areaLink.node; while(1) { for(kexWorldObject *obj = areaNode->objects.Next(); obj != NULL; obj = obj->areaLink.link.Next()) { if(obj == this || !obj->bCollision) { continue; } if(target && obj != target) { continue; } dist = ObjectDistance(obj, dmgOrigin); if(kexMath::Sqrt(dist) * 0.5f < radius + dmgRadius) { InflictDamage(obj, defManager.FindDefEntry(damageDef)); return true; } } if(areaNode->axis == -1) { break; } if(bbox.min[areaNode->axis] > areaNode->dist) { areaNode = areaNode->children[NODE_FRONT]; } else if(bbox.max[areaNode->axis] < areaNode->dist) { areaNode = areaNode->children[NODE_BACK]; } else { break; } } } return false; }
public func Activate(oCaller, oClonk) { if(!oClonk) oClonk = oCaller; // Effekt prüfen var iChkEff; if (iChkEff = CheckEffect("WarmPSpell", oExtiObj, 180)) return(iChkEff!=-1 && RemoveObject()); // Nächstes gerforenes Objekt finden var oExtiObj, iExtiCount, pObj; // Den Clonk selbst? if(Frozen(oClonk)) iExtiCount += DoUnfreeze(oClonk, oCaller); else if(oClonk->~MagicWarm(1800)) iExtiCount += DoUnfreeze(oClonk, oCaller); else if(pObj = Contents(0,oClonk)) if(GetID(pObj)==METL) if(GetDefHeight(ANML)) { RemoveObject(pObj); CreateContents(ANML, oClonk); return(RemoveObject()); } // Nächstliegende Objekte SetPosition(GetX(oCaller), GetY(oCaller)); // Suchradius ist abhängig von Höhe des Aufrufenden - ein Zauberturm hat einen größeren Radius var iSearchRadius = GetObjHeight(oCaller) * 3; while(oExtiObj = FindObject(0, 0, 0, -1, -1, 0, 0, 0, 0, oExtiObj)) if(ObjectDistance(oCaller, oExtiObj) > iSearchRadius) break; else if(Frozen(oExtiObj)) iExtiCount += DoUnfreeze(oExtiObj, oCaller); else if (oExtiObj->~MagicUnfreeze(oCaller)) iExtiCount += DoUnfreeze(oExtiObj, oCaller); // Irgendwas erwärmt? if (!iExtiCount) { Message("$NoUnfreeze$", oClonk); RemoveObject(); return 0; } // Einmaliger Effekt pro Zauber Sound("Inflame"); return(true); }
//Such nach einem Objekt, dass ein Acquire-Command holen könnte global func GetAvailableObject (def, xobj) { var obj; // Next closest while (obj = FindObject (def, 0, 0, -1, -1, OCF_Available (), 0, 0, 0, obj)) { if (ObjectDistance (obj) > 559) return (); // Object is near enough if (!Inside (GetX () - GetX (obj), -500, +500)) continue; if (!Inside (GetY () - GetY (obj), -250, +250)) continue; // Object is not connected to a pipe (for line construction kits) if (FindObject (SPIP, 0, 0, 0, 0, 0, "Connect", obj)) continue; if (FindObject (DPIP, 0, 0, 0, 0, 0, "Connect", obj)) continue; // Must be complete if (~GetOCF (obj) & OCF_Fullcon ()) continue; // Doesn't burn if (OnFire( obj)) continue; // Not contained in xobj if (!(Contained (obj) == xobj) || !xobj) // We found one break; } return (obj); }
public func Activate(caster, real_caster) { // Zaubernden Clonk ermitteln var clonk = caster; if (real_caster) clonk = real_caster; // Richtungsvorzeichen ermitteln var dir_sign = -1; if (GetDir(caster) == DIR_Right()) dir_sign = +1; // Evtl. mit Flint kombinieren var obj; if (obj = FindContents(FLNT, clonk)) { // Holz erzeugen, anzünden und in Guckrichtung schleudern var wood = CreateObject(WOOD, 5*dir_sign, 0, -1); Incinerate(wood); // Richtigen Controller setzen SetController(GetController(clonk),wood); SetXDir(40*dir_sign, wood); SetYDir(-10, wood); // Flint verbrauchen RemoveObject(obj); } // Evtl. mit Pfeil kombinieren else { obj = FindContents(ARRW, clonk); if(!obj) if(FindContents(ARWP, clonk)) obj = FindContents(ARWP, clonk)->GetItem(); if(obj) { // Ein paar Objekte schleudern var fling_cnt = RandomX(4, 10); var fling_obj; while (fling_obj = FindObject(0, 0, 0, -1, -1, OCF_InFree(), 0, 0, NoContainer(), fling_obj)) { // Zu weit weg vom Clonk? if (ObjectDistance(clonk, fling_obj) > 5*GetDefCoreVal("Width", "DefCore", GetID(caster))) break; // Der Wolf konnte keine Steinhütten wegblasen - Clonks können keine Hütten mit Fundament wegblasen if (!LocalN("basement", fling_obj)) { var pBasement = Local(9, fling_obj); if (GetType(pBasement) != C4V_C4Object()) pBasement=0; if (pBasement) if (!PrivateCall(pBasement, "BasementID")) pBasement=0; if (!pBasement) { SetXDir(dir_sign*Min(80, 80*350/GetMass(fling_obj)), fling_obj); SetYDir(-Min(20, 20/GetMass(fling_obj)), fling_obj); // Bei Objekten noch den Controller anpassen if(GetCategory(fling_obj) & C4D_Object()) SetController(GetController(clonk),fling_obj); } } // Schon genügend Objekte geschleudert? if (!fling_cnt--) break; } if (!Contained(clonk)) { Fling(clonk, 8*dir_sign, -2); } // Pfeil verbrauchen RemoveObject(obj); } // Sonst normale Wirkung else { AddEffect("WindUSpell", 0, 104, 50, 0, GetID(), GetDir(caster)); Sound("Wind2"); } } RemoveObject(); return(1); }
global func DoFireBreath(proplist fx, int x, int y, int tx, int ty, int timer) { var anim_length = 12; var sx = x - 3 + 6 * fx.cyclops->GetDir(); var sy = y - 15; // effects if (fx.spraying_charge <= 0) { if (ObjectDistance(fx.cyclops, fx.target) < CYCLOPS_FireBreath_Reach && fx.spraying < CYCLOPS_FireBreath_Duration) { var action = "IdleLookAround"; fx.cyclops->PlayAnimation(action, CLONK_ANIM_SLOT_Arms, Anim_Linear(0, 0, fx.cyclops->GetAnimationLength(action), anim_length, ANIM_Remove), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); fx.spraying_charge = 1; } } else if (fx.spraying_charge < anim_length) { fx.spraying_charge++; if (fx.spraying_charge >= anim_length) { fx.cyclops->Sound("BalloonInflate"); } } else if (fx.spraying < CYCLOPS_FireBreath_Duration) { var target_angle = Normalize(Angle(sx, sy, tx, ty), -180); var source_angle = -90 + fx.cyclops->GetDir() * 180; var a = Min(CYCLOPS_FireBreath_Duration, fx.spraying * 2); var b = CYCLOPS_FireBreath_Duration - a; var angle = (b * source_angle + a * target_angle) / CYCLOPS_FireBreath_Duration; angle = Normalize(angle, -180); var head_angle = Normalize(angle - source_angle, -180); // turn his head towards the clonk // somehow the turning head makes the cyclops invisible, though var transform = Trans_Rotate(10, 0, 0, 1); //var transform = Trans_Rotate(head_angle, 0, 0, 1); if (!fx.anim_nr) { fx.anim_nr = fx.cyclops->TransformBone("skeleton_head", transform, 5, Anim_Const(1000)); } else { fx.cyclops->SetAnimationBoneTransform(fx.anim_nr, transform); } fx.spraying = Min(CYCLOPS_FireBreath_Duration, fx.spraying + 1); var distance = Min(CYCLOPS_FireBreath_Reach, ObjectDistance(fx.cyclops, fx.target)); FireBreathEffect(fx, angle, distance, sx, sy, timer); FireBreathDamage(fx, angle, distance, sx, sy); } else { // cooldown and reset fx.spraying = Min(2 * CYCLOPS_FireBreath_Duration, Max(CYCLOPS_FireBreath_Duration + 1, fx.spraying + 1)); if (fx.spraying == 2 * CYCLOPS_FireBreath_Duration) { fx.spraying = 0; fx.spraying_charge = 0; fx.spray_old = {time = 0, v0 = 0, v1 = 0, reach = 0}; fx.spray_cur = {time = 0, v0 = 0, v1 = 0, reach = 0}; } } }