/* * $Header: /HexenWorld/Siege/object.hc 13 5/31/98 2:59p Mgummelt $ */ float SPAWNFLAG_BALLISTA_TRACK = 1; /* * obj_push() -- Allows players to push objects when they walk toward them. */ void() Missile_Arc; void(float vol) sheep_sound; void() obj_barrel_roll; void()float; void()sheep_trot; void fix_vel () { self.enemy.velocity=self.mangle; remove(self); } void obj_fly_hurt (entity loser) {//MG //FIXME: Check for sky //dprint("hit\n"); float magnitude,my_mass; if(self.classname=="player_sheep"&&self.teleport_time+10&&other.classname=="snowball") return; if(self.classname=="player") { my_mass=self.mass; } else { if(!self.mass) my_mass = 1; else if(self.mass<=10) my_mass=10; else my_mass = self.mass/10; } magnitude=vlen(self.velocity)*my_mass/10; if(pointcontents(self.absmax)==CONTENT_WATER)//FIXME: or other watertypes magnitude/=3; //water absorbs 2/3 velocity if(self.classname=="barrel"&&self.aflag)//rolling barrels are made for impacts! magnitude*=3; if(self.frozen>0&&magnitude<300&&self.flags&FL_ONGROUND&&loser==world&&self.velocity_z<-20&&self.last_onground+0.3 "); dprint(loser.classname); dprint("\n"); dprint(vtos(self.velocity)); dprint("\n"); dprint("Magnitude: "); dprint(ftos(magnitude)); dprint("\n"); dprint("Air time: "); dprint(ftos(time-self.last_onground)); dprint("\n"); dprint("Time since last impact: "); dprint(ftos(time-self.last_impact)); dprint("\n"); } */ if(self.last_onground+0.3=THINGTYPE_GLASS)) { vector dir1, dir2; float force,dot; if(loser.thingtype>=THINGTYPE_GLASS) magnitude*=2; if(magnitude>=100&&loser.takedamage&&loser.classname!="catapult"&&loser!=world) { dir1=normalize(self.velocity); if(loser.origin=='0 0 0') dir2=dir1; else dir2=normalize(loser.origin-self.origin); dot= dir1*dir2; if(dot >= 0.2) force=dot; else force=0; force*=magnitude/50; if(pointcontents(loser.absmax)==CONTENT_WATER||(self.classname=="barrel"&&self.aflag))//FIXME: or other watertypes force/=3; //water absorbs 2/3 velocity if(self.flags&FL_MONSTER&&loser==world) force/=2; if(self.frozen>0&&force>10) force=10; if((force>=1&&loser.classname!="player")||force>=10) { /* dprint("Damage other ("); dprint(loser.classname); dprint("): "); dprint(ftos(force)); dprint("\n"); */ T_Damage (loser, self, self, force); if(loser.health<=0) {//Keep 75% of vel if broke loser apart // dprint("Broke through\n"); newmis=spawn(); newmis.mangle=self.velocity*0.75; newmis.think=fix_vel; newmis.enemy=self; thinktime newmis : HX_FRAME_TIME; } } } if(self.classname!="monster_mezzoman"&&self.netname!="spider"&&self.beast_time=100+self.health&&self.classname!="player")||(magnitude>=700&&self.safe_time=time)//crouching on impact absorbs 1/2 the damage magnitude/=2; } magnitude/=40; magnitude=magnitude - force/2;//If damage other, subtract half of that damage off of own injury if(dmMode==DM_SIEGE) force*=3; if(magnitude>=1) { //FIXME: Put in a thingtype impact sound function /* dprint("Damage self ("); dprint(self.classname); dprint("): "); dprint(ftos(magnitude)); dprint("\n"); */ // if(self.classname=="player_sheep"&&self.flags&FL_ONGROUND&&self.velocity_z>-50) // return; T_Damage(self,world,world,magnitude); } } self.last_impact=time; if(self.flags&FL_ONGROUND) self.last_onground=time; } } void obj_push() {//MG vector pushdir,pushangle,fpv; float ontop,pushed,inertia,force,walkforce; if(other.solid==SOLID_PHASE||other.movetype==MOVETYPE_FLYMISSILE||other.movetype==MOVETYPE_BOUNCEMISSILE) return; if(self.classname=="barrel"&&pointcontents(self.origin)!=CONTENT_EMPTY&&(!self.spawnflags&BARREL_SINK)) { self.classname="barrel_floating"; self.think=float; self.nextthink=time; } if(self.classname=="player_sheep"&&other.classname=="catapult") { self.spawnflags(+)1; //Sheep won't move once on catapult self.speed=0; } if(self.last_impact + 0.1<=time) obj_fly_hurt(other); // if (other.classname != "player"&&!(other.flags&FL_MONSTER)&&(!other.flags&FL_PUSH)&&other.movetype!=MOVETYPE_PUSHPULL) // return; if(other!=world&&other.absmin_z >= self.origin_z+self.maxs_z - 5&&other.velocity_z<1) { if(!other.frozen&& ( (!other.flags2&FL_ALIVE&&other.flags&FL_MONSTER)|| (self.flags&FL_MONSTER&&self.model!="models/spider.mdl"&&self.model!="models/scorpion.mdl") ) ) { makevectors(other.angles); v_forward_z=1; other.velocity=v_forward*300; other.flags(-)FL_ONGROUND; } if(other.flags&FL_CLIENT&&!other.frozen) ontop = FALSE; else { ontop=TRUE; // other.flags(+)FL_ONGROUND; } } if(self.flags&FL_MONSTER) { if(other!=world&&self.absmin_z >= other.absmax_z - 3&&self.velocity_z<1&&other.movetype!=MOVETYPE_FLYMISSILE&&other.movetype!=MOVETYPE_BOUNCE&&other.movetype!=MOVETYPE_BOUNCEMISSILE) self.flags(+)FL_ONGROUND; if(self.frozen<=0&&!self.artifact_active&ARTFLAG_STONED) return; } // if(self.classname=="barrel"&&other.classname=="player") // dprintv("Player hit me with vel: %s\n",other.velocity); if(!other.velocity) return; if (self.impulse == 20) return; if(!self.mass) inertia=1; if(self.mass<=30) inertia=self.mass/3; else inertia=self.mass/33; if(other.strength) force=vlen(other.velocity)*(other.strength/40+0.5); else force=vlen(other.velocity); if(pointcontents(self.origin)==CONTENT_WATER||pointcontents(self.origin)==CONTENT_SLIME||pointcontents(self.origin)==CONTENT_LAVA) force/=3; //FIXME: mass should determine how fast the object can be pushed // if (self.mass > 199*force) // Too heavy to move if (self.mass >= 1000) // Too heavy to move return; //So you can push frozen guys around before they melt if(self.frozen>0) { self.freeze_time=time+10; self.wait=time + 10; } if(ontop) return; walkforce=force/inertia/40;//20 is the frame time... if(self.classname=="barrel"&&self.aflag) {//on side vector dir1, dir2; float dot_forward,dot_right; self.angles_z=0; self.v_angle_x=self.v_angle_z=0; makevectors(self.v_angle); if(ontop) dir1=normalize(other.velocity); else dir1=normalize(self.origin-other.origin); dir2=normalize(v_forward); dir1_z=dir2_z=0; dot_forward= dir1*dir2; self.enemy=other; if(dot_forward>=0.9) { self.movedir=dir2;//test self.movedir_z=0; self.speed += force/inertia; if(self.speed>other.strength*300) self.speed=other.strength*300; traceline(self.origin,self.origin+dir2*48,FALSE,self); if(trace_fraction==1.0) { self.velocity=self.movedir*self.speed; self.think=obj_barrel_roll; self.nextthink=time; } } else if(dot_forward<=-0.9) { self.movedir=dir2;//test self.movedir_z=0; self.speed += force/inertia*-1; if(self.speed0.2) { if(dot_forward >0.1) { self.angles_y-=walkforce*10; } else if(dot_forward<-0.1) { self.angles_y+=walkforce*10; } } else if(dot_right<-0.2) { if(dot_forward >0.1) { self.angles_y+=walkforce*10; } else if(dot_forward<-0.1) { self.angles_y-=walkforce*10; } } self.v_angle_y=self.angles_y; } } else { pushdir=normalize(other.velocity); pushdir_z=0;//no push into ground or up pushangle=vectoangles(pushdir); pushed=FALSE; walkforce=force/inertia/10;//20 is the frame rate... work in frametime? // if(self.classname=="barrel"&&other.classname=="player") // dprintf("Push force = %s\n",walkforce); if(!walkmove(pushangle_y,walkforce,FALSE))//FIXME: check mass { if(self.classname=="barrel")//trace_ent.classname=="catapult"&& { self.velocity=pushdir*100; self.velocity_z=80;//EZ Lift } else { if(other.absmax_z<=self.origin_z+self.mins_z*0.75) pushdir_z*=2; fpv=(pushdir*force*2*(1/inertia)+self.velocity)*0.5; self.velocity_x=fpv_x; self.velocity_y=fpv_y; } if(self.flags&FL_ONGROUND) { if(self.velocity_z<0) self.velocity_z=0; self.flags-=FL_ONGROUND; } if(self.velocity!='0 0 0') pushed=TRUE; } else pushed=TRUE; if(pushed&&self.classname!="barrel_floating") { if(self.pain_finished<=time) { if(self.classname=="player_sheep") { if(random()<0.3) sheep_sound(.75); if(!infront(other)&&random()<0.5&&self.speed) //FIXME- find current think and set transition to run self.think=sheep_trot; } else if(self.thingtype==THINGTYPE_WOOD||self.thingtype==THINGTYPE_WOOD_METAL) {//FIXME: make more net friendly sound(self,CHAN_VOICE,"misc/pushwood.wav",1,ATTN_NORM); self.pain_finished=time + 1.041; } else if ((self.thingtype==THINGTYPE_GREYSTONE) || (self.thingtype==THINGTYPE_BROWNSTONE)) { sound(self,CHAN_VOICE,"misc/pushston.wav",1,ATTN_NORM); self.pain_finished=time + .711; } else if(self.thingtype==THINGTYPE_METAL) { sound(self,CHAN_VOICE,"misc/pushmetl.wav",1,ATTN_NORM); self.pain_finished=time + .835; } } } } } /*QUAKED obj_chair (0.3 0.1 0.6) (-10 -10 -5) (10 10 40) A wooden chair. -------------------------FIELDS------------------------- none -------------------------------------------------------- */ void obj_chair() { precache_model("models/chair.mdl"); CreateEntityNew(self,ENT_CHAIR,"models/chair.mdl",chunk_death); self.touch = obj_push; self.flags = self.flags | FL_PUSH; } /*QUAKED obj_barstool (0.3 0.1 0.6) (-10 -10 -5) (10 10 32) A bar stool - Drinks on the house! -------------------------FIELDS------------------------- none -------------------------------------------------------- */ void obj_barstool() { precache_model3("models/stool.mdl"); CreateEntityNew(self,ENT_BARSTOOL,"models/stool.mdl",chunk_death); self.touch = obj_push; self.flags = self.flags | FL_PUSH; } /*QUAKED obj_tree (0.3 0.1 0.6) (-42 -42 0) (42 42 160) A tree that has no leaves -------------------------FIELDS------------------------- health : 1000 -------------------------------------------------------- */ void obj_tree() { precache_model2("models/tree.mdl"); CreateEntityNew(self,ENT_TREEDEAD,"models/tree.mdl",chunk_death); } void tree2_death (void) { self.owner.nextthink = time + .01; self.owner.think = chunk_death; chunk_death(); } /*QUAKED obj_tree2 (0.3 0.1 0.6) (-140 -140 -16) (140 140 220) A tree with a round top of leaves -------------------------FIELDS------------------------- health : 1000 -------------------------------------------------------- */ void obj_tree2() { entity top; precache_model("models/tree2.mdl"); CreateEntityNew(self,ENT_TREE,"models/tree2.mdl",tree2_death); top = spawn(); top.scale = self.scale; CreateEntityNew(top,ENT_TREETOP,top.model,tree2_death); top.origin = self.origin; if (self.scale) // Move top according to scale top.origin_z += top.scale * 104; else top.origin_z += 104; top.health = self.health; top.classname = "tree2top"; top.owner = self; self.owner = top; } /*QUAKED obj_bench (0.3 0.1 0.6) (-30 -30 0) (30 30 40) A wooden bench -------------------------FIELDS------------------------- none -------------------------------------------------------- */ void obj_bench() { precache_model3("models/bench.mdl"); CreateEntityNew(self,ENT_BENCH,"models/bench.mdl",chunk_death); self.touch = obj_push; } /*QUAKED obj_cart (0.3 0.1 0.6) (-36 -32 -10) (36 75 64) A cart -------------------------FIELDS------------------------- none -------------------------------------------------------- */ void obj_cart() { precache_model("models/cart.mdl"); CreateEntityNew(self,ENT_CART,"models/cart.mdl",chunk_death); self.hull=HULL_SCORPION; self.touch = obj_push; self.flags = self.flags | FL_PUSH; } /*QUAKED obj_chest1 (0.3 0.1 0.6) (-16 -16 0) (16 16 32) A treasure chest -------------------------FIELDS------------------------- skin - 0 - generic texture (default) 1 - roman texture -------------------------------------------------------- */ void obj_chest1() { precache_model("models/chest1.mdl"); CreateEntityNew(self,ENT_CHEST1,"models/chest1.mdl",chunk_death); self.touch = obj_push; self.flags = self.flags | FL_PUSH; } /*QUAKED obj_chest2 (0.3 0.1 0.6) (-16 -16 0) (16 16 32) A treasure chest on legs -------------------------FIELDS------------------------- skin - 0 - generic texture (default) 1 - meso texture 2 - egypt texture -------------------------------------------------------- */ void obj_chest2() { precache_model3("models/chest2.mdl"); CreateEntityNew(self,ENT_CHEST2,"models/chest2.mdl",chunk_death); self.touch = obj_push; self.flags = self.flags | FL_PUSH; } /*QUAKED obj_chest3 (0.3 0.1 0.6) (-16 -16 0) (16 16 32) A treasure chest on legs -------------------------FIELDS------------------------- none -------------------------------------------------------- */ void obj_chest3() { precache_model2("models/chest3.mdl"); CreateEntityNew(self,ENT_CHEST3,"models/chest3.mdl",chunk_death); self.touch = obj_push; self.flags = self.flags | FL_PUSH; } /* void boulder_fall (void) { if(!self.flags&FL_ONGROUND||self.frags=0) self.velocity_z-=10; } self.think=boulder_fall; self.nextthink=time+0.1; } void boulder_push() { if(self.velocity) self.avelocity=self.velocity*-1; obj_fly_hurt(other); if(other.movetype&&other.velocity!='0 0 0'&&other.solid!=SOLID_TRIGGER&&other.solid!=SOLID_PHASE&&other.solid) { if(!walkmove(other.angles_y,1,TRUE)) { dprint("can't walk\n"); self.velocity=(other.velocity+self.velocity)*0.5; self.frags=time+0.01; } if(self.flags&FL_ONGROUND) { self.movetype=MOVETYPE_BOUNCEMISSILE;//movetype_slide- no friction self.flags-=FL_ONGROUND; } } } */ /*QUAK-ED obj_boulder (0.3 0.1 0.6) (-32 -32 -32) (32 32 32) A big freaking rock -------------------------FIELDS------------------------- health = 75 mass = 25 -------------------------------------------------------- */ /* void obj_boulder (void) { precache_model2("models/boulder.mdl"); CreateEntityNew(self,ENT_BOULDER,"models/boulder.mdl",chunk_death); self.flags = self.flags | FL_PUSH; self.touch = obj_push; // self.think=boulder_fall; // self.nextthink=time+0.1; } */ /*QUAKED obj_sword (0.3 0.1 0.6) (-16 -16 -8) (16 16 8) A sword -------------------------FIELDS------------------------- health = 50 -------------------------------------------------------- */ void obj_sword (void) { precache_model("models/sword.mdl"); CreateEntityNew(self,ENT_SWORD,"models/sword.mdl",chunk_death); if(self.targetname) self.use=chunk_death; } /* void BalBoltStick (void) { vector dir; self.velocity='0 0 0'; self.movetype=MOVETYPE_NONE; self.solid=SOLID_BBOX; self.takedamage=DAMAGE_YES; if (!self.health) self.health=10; self.th_die=chunk_death; makevectors(self.angles); dir=normalize(v_forward); if(pointcontents(self.origin+dir*24)!=CONTENT_SOLID) remove(self); } */ void BalBoltTouch (void) { if(other.takedamage) { vector dir; //FIXME: Skewer them if(other!=self.goalentity&&self.velocity!='0 0 0') { self.goalentity=other; dir=normalize(self.velocity); traceline(self.origin-dir*25,self.origin+dir*25,FALSE,self); if(other.thingtype==THINGTYPE_FLESH) MeatChunks (trace_endpos,self.velocity*0.5+'0 0 200', 3,trace_ent); SpawnPuff (trace_endpos, self.velocity*0.5+'0 0 200', self.dmg,trace_ent); // if(other.health+20my_pitch_z) { if(ideal_pitch_z-my_pitch_z>self.count) pitchmod=self.count; else pitchmod=ideal_pitch_z-my_pitch_z; self.angles_z+=pitchmod; } else if(ideal_pitch_zself.count) pitchmod=self.count; else pitchmod=my_pitch_z-ideal_pitch_z; self.angles_z-=pitchmod; } if(self.last_attack+self.speedself.friction) other.flags-=FL_ONGROUND; } void ice_slab_melt (void) { if(self.scale>0.05) { self.scale-=0.05; setsize(self,self.mins*0.9,self.maxs*0.9); thinktime self : 0.1; } else remove(self); } void obj_ice (void) { //thingtype_ice, need ice chunks if(self.flags2&FL_SUMMONED) { //Make pushable, floating?! self.solid = SOLID_BBOX; self.movetype = MOVETYPE_NONE; self.drawflags(+)SCALE_TYPE_XYONLY; self.scale = 1; self.think = ice_slab_melt; thinktime self : 10; } else { self.solid = SOLID_BSP; self.movetype = MOVETYPE_PUSH; } self.takedamage=DAMAGE_YES; self.thingtype = THINGTYPE_ICE; setorigin (self, self.origin); setmodel (self, self.model); self.frozen=TRUE; self.classname="ice"; self.use = chunk_death; self.drawflags+=MLS_ABSLIGHT; if(!self.abslight) self.abslight = 0.75; if(!self.spawnflags&1) self.drawflags+=DRF_TRANSLUCENT; if(!self.health) self.health = 20; self.max_health = self.health; if(!self.friction) self.friction = 0.2; // self.touch = friction_change_touch; self.touch = ice_touch; self.th_die = chunk_death; } /*QUAKED obj_beefslab (0.3 0.1 0.6) (-16 -16 0) (16 16 40) A slab of beef. -------------------------FIELDS------------------------- health = 50 -------------------------------------------------------- */ void obj_beefslab (void) { precache_model3("models/beefslab.mdl"); CreateEntityNew(self,ENT_BEEFSLAB,"models/beefslab.mdl",chunk_death); } /*QUAKED obj_seaweed (0.3 0.1 0.6) (-8 -8 0) (8 8 32) An animate seaweed that sways from side to side. -------------------------FIELDS------------------------- health = 10 -------------------------------------------------------- */ void obj_seaweed (void) { precache_model("models/seaweed.mdl"); CreateEntityNew(self,ENT_SEAWEED,"models/seaweed.mdl",chunk_death); } /*QUAKED obj_statue_lion (0.3 0.1 0.6) (-56 -14 0) (56 14 60) Statue of a lion. -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_lion(void) { precache_model2("models/lion.mdl"); CreateEntityNew(self,ENT_STATUE_LION,"models/lion.mdl",chunk_death); self.drawflags += SCALE_ORIGIN_BOTTOM; } /*QUAKED obj_statue_athena(0.3 0.1 0.6) (-30 -30 0) (30 30 90) Statue of a Athena -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_athena (void) { precache_model2("models/athena.mdl"); CreateEntityNew(self,ENT_STATUE_ATHENA,"models/athena.mdl",chunk_death); self.drawflags += SCALE_ORIGIN_BOTTOM; } /*QUAKED obj_statue_neptune(0.3 0.1 0.6) (-30 -30 0) (30 30 100) Statue of Neptune (I think) -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_neptune (void) { precache_model2("models/neptune.mdl"); CreateEntityNew(self,ENT_STATUE_NEPTUNE,"models/neptune.mdl",chunk_death); self.drawflags += SCALE_ORIGIN_BOTTOM; } /*QUAKED obj_bonepile(0.3 0.1 0.6) (-10 -10 0) (10 10 10) A pile of bones. Uses the model of the puzzle keep1 -------------------------FIELDS------------------------- health = -------------------------------------------------------- */ void obj_bonepile (void) { precache_model3("models/bonepile.mdl"); CreateEntityNew(self,ENT_BONEPILE,"models/bonepile.mdl",chunk_death); self.use = chunk_death; self.drawflags += SCALE_ORIGIN_BOTTOM; } /*QUAKED obj_statue_caesar(0.3 0.1 0.6) (-24 -24 0) (24 24 90) Statue of a Caesar Romero -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_caesar (void) { precache_model2("models/caesar.mdl"); CreateEntityNew(self,ENT_STATUE_CAESAR,"models/caesar.mdl",chunk_death); self.drawflags += SCALE_ORIGIN_BOTTOM; } /*QUAKED obj_statue_snake_coil (0.3 0.1 0.6) (-44 -44 0) (44 44 90) Statue of a coiled snake (just like the one that comes to life) but this one doesn't come to life. -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_snake_coil (void) { precache_model2 ("models/snake.mdl"); CreateEntityNew(self,ENT_STATUE_SNAKE_COIL,"models/snake.mdl",chunk_death); self.scale = .5; self.drawflags += SCALE_ORIGIN_BOTTOM; } /*QUAKED obj_skull (0.3 0.1 0.6) (-8 -8 0) (8 8 16) A skull, suitable for over the fireplace or perhaps a colorful holiday display -------------------------FIELDS------------------------- health = 10 -------------------------------------------------------- */ void obj_skull (void) { precache_model("models/skull.mdl"); CreateEntityNew(self,ENT_SKULL,"models/skull.mdl",chunk_death); } /*QUAKED obj_pew (0.3 0.1 0.6) (-16 -40 0) (16 40 50) A church pew - like you might find in a church. -------------------------FIELDS------------------------- health = 50 -------------------------------------------------------- */ void obj_pew (void) { precache_model("models/pew.mdl"); CreateEntityNew(self,ENT_PEW,"models/pew.mdl",chunk_death); } /*QUAKED obj_statue_olmec (0.3 0.1 0.6) (-40 -40 0) (40 40 130) A olmec statue, of course. What the heck is an olmec? -------------------------FIELDS------------------------- health = 50 -------------------------------------------------------- */ void obj_statue_olmec (void) { precache_model2("models/olmec1.mdl"); CreateEntityNew(self,ENT_STATUE_OLMEC,"models/olmec1.mdl",chunk_death); } /*QUAKED obj_statue_mars (0.3 0.1 0.6) (-30 -30 0) (30 30 80) A statue of Mars. -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_mars (void) { precache_model2("models/mars.mdl"); CreateEntityNew(self,ENT_STATUE_MARS,"models/mars.mdl",chunk_death); } /*QUAKED obj_playerhead_paladin (0.3 0.1 0.6) (-8 -8 0) (8 8 16) The head of the paladin. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_playerhead_paladin (void) { precache_model("models/h_pal.mdl"); CreateEntityNew(self,ENT_PLAYERHEAD,"models/h_pal.mdl",chunk_death); self.use=chunk_death; } /*QUAKED obj_playerhead_assassin (0.3 0.1 0.6) (-8 -8 0) (8 8 16) The head of the assassin. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_playerhead_assassin (void) { precache_model("models/h_ass.mdl"); CreateEntityNew(self,ENT_PLAYERHEAD,"models/h_ass.mdl",chunk_death); self.use=chunk_death; } /*QUAKED obj_playerhead_necromancer (0.3 0.1 0.6) (-8 -8 0) (8 8 16) The head of the necromancer. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_playerhead_necromancer (void) { precache_model("models/h_nec.mdl"); CreateEntityNew(self,ENT_PLAYERHEAD,"models/h_nec.mdl",chunk_death); self.use=chunk_death; } /*QUAKED obj_playerhead_crusader (0.3 0.1 0.6) (-8 -8 0) (8 8 16) The head of the crusader. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_playerhead_crusader (void) { precache_model("models/h_cru.mdl"); CreateEntityNew(self,ENT_PLAYERHEAD,"models/h_cru.mdl",chunk_death); self.use=chunk_death; } /*QUAKED obj_statue_king (0.3 0.1 0.6) (-30 -30 0) (30 30 120) A statue of a king holding a sword in front of him. -------------------------FIELDS------------------------- health = 200 -------------------------------------------------------- */ void obj_statue_king (void) { precache_model3("models/king.mdl"); CreateEntityNew(self,ENT_STATUE_KING,"models/king.mdl",chunk_death); self.mins -= '0 0 80'; self.maxs -= '0 0 80'; setsize(self, self.mins, self.maxs); } /*QUAKED obj_plant_generic (0.3 0.1 0.6) (-10 -10 0) (10 10 20) A generic plant that should have some kind of pot placed below it. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_plant_generic (void) { precache_model("models/plantgen.mdl"); CreateEntityNew(self,ENT_PLANT_GENERIC,"models/plantgen.mdl",chunk_death); } /*QUAKED obj_plant_meso (0.3 0.1 0.6) (-10 -10 0) (10 10 40) A generic plant that should have some kind of pot placed below it. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_plant_meso (void) { precache_model2("models/plantmez.mdl"); CreateEntityNew(self,ENT_PLANT_MESO,"models/plantmez.mdl",chunk_death); } /*QUAKED obj_plant_rome (0.3 0.1 0.6) (-24 -24 0) (24 24 90) A plant for the Rome area. -------------------------FIELDS------------------------- health = 20 -------------------------------------------------------- */ void obj_plant_rome (void) { precache_model2("models/plantrom.mdl"); CreateEntityNew(self,ENT_PLANT_ROME,"models/plantrom.mdl",chunk_death); } /*QUAKED obj_skeleton_throne (0.3 0.1 0.6) (-33 -33 -0) (33 33 115) */ void obj_skeleton_throne (void) { entity sk_king,box2,box3; precache_model("models/throne.mdl"); precache_model("models/sk-throne.mdl"); CreateEntityNew(self,ENT_SKELTHRN,"models/throne.mdl",SUB_Null); self.drawflags(+)SCALE_ORIGIN_BOTTOM; sk_king=spawn(); self.movechain=sk_king; setmodel(sk_king,"models/sk-throne.mdl"); setsize(sk_king,'0 0 0','0 0 0'); setorigin(sk_king,self.origin); sk_king.angles=self.angles; sk_king.drawflags(+)SCALE_ORIGIN_BOTTOM; if(self.abslight) { self.drawflags(+)MLS_ABSLIGHT; sk_king.abslight=self.abslight; sk_king.drawflags(+)MLS_ABSLIGHT; } makevectors(self.angles); box2=spawn(); box2.solid=SOLID_BBOX; setsize(box2,'-26 -26 0','26 26 36'); setorigin(box2,self.origin-v_forward*7); box3=spawn(); box3.solid=SOLID_BBOX; if(self.angles_y==0||self.angles_y==180) setsize(box3,'-4 -30 0','4 30 115'); else setsize(box3,'-30 -4 0','30 4 115'); setorigin(box3,self.origin-v_forward*29); } void let_go_excal () { entity oself; sound(other,CHAN_AUTO,"weapons/unsheath.wav",1,ATTN_NORM); dprint(other.netname); dprint(" is The Defender of the Crown!"); centerprint_all_clients("The Defender of the Crown has been chosen!\n",other); centerprint(other,"You have been chosen as Halcyon's succesor!@Excelsior is yours, go forth and smite@thine enemies righteously!"); other.flags2(+)FL2_EXCALIBUR; other.effects(+)EF_LIGHT; other.health=other.max_health; other.oldweapon = FALSE; other.weapon = IT_WEAPON1; oself=self; self=other; restore_weapon(); PlayerSpeed_Calc(self); self=oself; WriteByte (MSG_ALL, SVC_MIDI_NAME); WriteString (MSG_ALL, "ofortuna"); WriteTeam (SVC_ISDOC,other); remove(self); } void excal_reset () { self.frame = 16; self.nextthink = -1; } void()excal_swing2 = [++39 .. 51] { if(cycle_wrapped) { self.attack_finished=time+0.5; self.think=excal_reset; thinktime self : 0.05; } else { if(self.frame==43) sound (self, CHAN_VOICE, "weapons/met2flsh.wav", 1, ATTN_NORM); T_Damage(other,self,self,10); } }; void()excal_swing1 = [++17 .. 38] { if(cycle_wrapped) { self.attack_finished=time+0.5; self.think=excal_reset; thinktime self : 0.05; } else { if(self.frame==23) sound (self, CHAN_VOICE, "weapons/met2flsh.wav", 1, ATTN_NORM); T_Damage(other,self,self,10); } }; void check_siege_team () { if(self.attack_finished>time) return; if(other.siege_team==ST_DEFENDER) { if(other.playerclass==CLASS_PALADIN) let_go_excal(); } else { sound (self, CHAN_WEAPON, "weapons/vorpswng.wav", 1, ATTN_NORM); if(random()<0.5) excal_swing1(); else excal_swing2(); } } void wait_for_paladin () { self.solid=SOLID_TRIGGER; setsize(self,'-24 -24 0','24 24 64'); self.touch = check_siege_team; } void () bestow_excalibur = [++0 .. 16] { if(self.frame==7) starteffect(CE_RIPPLE, self.origin,'0 0 0',2);//splash sound else if(random()<0.5) starteffect(CE_RIPPLE, self.origin,'0 0 0',1);//no drip sound //FIXME: water particles? splashing up? if(self.frame==16) { self.effects=EF_BRIGHTLIGHT; self.think=wait_for_paladin; thinktime self : 0.1; } }; void ready_bestow_excalibur2 () { centerprint_all_clients("Excelsior has Arisen!\n",world); setmodel(self,"models/lakeswd.mdl"); bestow_excalibur(); } void ready_bestow_excalibur () { if(activator.siege_team==ST_DEFENDER) return;//so defenders can't give themselves Excalibur early if(self.fail_chance) if(random(100)