main local.origin local.angles local.bulletsanger local.angertime: local.thing = spawn trigger_use //targetname local.name // to eliminate name parameter, add "entnum" to targetname after "level waittill spawn". local.thing model models/animal/german_shepherd.tik local.thing.origin = local.origin local.thing.angles = local.angles local.thing setsize ( -30 -30 -10 ) ( 30 30 50 ) local.thing droptofloor local.thing show local.thing anim dog_stand_idle local.thing light .4 .18 0 150 local.thing message "*** You have transformed into a living dog. ***" local.thing setthread player local.thing2 = spawn trigger_multiple spawnflags 128 //local.thing2 model "items/cigarette.tik" local.thing2.origin = local.origin local.thing2 setsize ( -50 -50 -20 ) ( 50 50 50 ) local.thing2.scale = 0.01 local.thing2 light 1 .75 0 50 //local.thing2 notsolid // if using a model for a trigger, do not add "notsolid", otherwise "setthread" will not work. local.thing2.bulletsanger = local.bulletsanger local.thing2.angertime = local.angertime * 10 // for-loop counter increments every 0.1 seconds. local.thing2.shot = 0 local.thing2.runonce = 0 local.thing2.angrydog = 0 local.thing2 setthread dogtrig_shot level waittill spawn local.thing.targetname = ("dogtrig" + local.thing.entnum) local.thing2.name = local.thing.targetname local.thing thread dog_anims end dog_anims: if(self.animsave == NIL) // dog only idles for 20 seconds after map starts, then it's always walking or resting. { self.animsave = 0 wait 5 if(self.animsave < 3 && self.angrydog != 1) { self anim dog_stand_idle; self.animsave = 0 } // "animsave" indicates the animation to return to, after dog is shot at and pain animation ends. wait 5 if(self.animsave < 3 && self.angrydog != 1) { self anim dog_stand_idle; self.animsave = 0 } // the dog barks once, each time the "idle" anim runs. wait 5 if(self.animsave < 3 && self.angrydog != 1) { self anim dog_stand_idle; self.animsave = 0 } // 0 = idle, 1 = walking, 2 = resting, 3 = curious (angry and ready to kill players), 4 = discipline (after anger is done). wait 5 } while(1) { // if dog is already walking, don't run another "dog_walk_leash" anim. if(self.animsave < 3 && local.dogwalking != 1 && self.angrydog != 1) { self anim dog_walk_leash; self.animsave = 1; local.dogwalking = 1 } wait 30 local.r = randomint(2) // if local.r = 0, dog keeps walking. otherwise, rest & end this thread. if(local.r == 1) { if(self.animsave < 3 && self.angrydog != 1) { self anim dog_rest; self.animsave = 2; break } } } end dogtrig_shot: self nottriggerable if(self.shot < self.bulletsanger && $(self.name).animsave != 4) // begin counting when dog gets shot at, only run one "shot_reset" thread. { self.shot++ if(self.runonce != 1) { self thread shot_reset } } if(self.shot >= self.bulletsanger) { self.runonce = 0; self thread shot_reset } if(self.takingpain != 1) { self thread dogpain } self light 1 1 1 50 $(self.name) light 1 1 1 150 waitframe self light 1 .75 0 50 if($(self.name).angrydog != 1) { $(self.name) light .4 .18 0 150 } if($(self.name).angrydog == 1) { $(self.name) light 1 0 0 150 } if(self.shot >= self.bulletsanger && self.angrydog != 1) { self.angrydog = 1 } self triggerable end dogpain: self.takingpain = 1 if($(self.name).animsave != 2 && $(self.name).animsave != 4) { local.r = randomint(3) if(local.r == 0) { $(self.name) anim dog_pain_head } if(local.r == 1) { $(self.name) anim dog_pain_front } if(local.r == 2) { $(self.name) anim dog_pain_back } wait 0.5 } if($(self.name).animsave == 0) { $(self.name) anim dog_stand_idle } // return to original animation before getting shot. if($(self.name).animsave == 1) { $(self.name) anim dog_walk_leash } if($(self.name).animsave == 2) { $(self.name) anim dog_standup self.shot = 0 wait 0.3 $(self.name).animsave = 1 $(self.name) thread dog_anims // if resting dog was shot, stand him up, then begin walking again. } if($(self.name).animsave == 3) { $(self.name) anim dog_stand_curious } self.takingpain = 0 end shot_reset: self.runonce = 1 for(local.c = 0; local.c <= 40; local.c++) // after 4 seconds and if self.shot < self.bulletsanger, then make self.shot = 0. { if(self.shot >= self.bulletsanger || self.angrydog == 1) { break } wait 0.1 } if(local.c >= 40 && self.shot < self.bulletsanger) // if the 4-second counter ended before the dog was shot "bulletsanger" times, then make "shot = 0" again. { self.shot = 0 self.angrydog = 0 $(self.name).angrydog = 0 self.runonce = 0 local.c = 0 } if($(self.name).animsave > 2) { end } // if dog is still angry, then end this thread immediately. local.c = 0 for(local.a = 0; self.angrydog == 1 && local.a <= self.angertime; local.a++) // dog is now angry and ready to bite players, angry for "angetime" seconds. { self light 1 .75 0 50 $(self.name) light 1 0 0 150 if(local.a < 1 || (local.c >= 50 && local.a < (self.angertime - 4))) { $(self.name) anim dog_stand_curious; $(self.name).animsave = 3; local.c = 0 } $(self.name).angrydog = 1 $(self.name) nottriggerable // nobody can become a dog when the dog is angry. self thread biteplayers wait 0.1 local.c++ // loop dog_stand_curious animations every 4 seconds. if(self.takingpain == 1) { local.c = 0 } } if(local.a >= self.angertime) { self light 1 .75 0 50 $(self.name) light .4 .18 0 150 $(self.name).angrydog = 0 self.angrydog = 0 self.shot = 0 $(self.name).scale = 0.001 // "hide" turns off the light. $(self.name).angles = $(self.name).angles + ( 0 180 0 ) // dog must be rotated 180 degrees when using "dog_discipline". waitframe $(self.name).scale = 1 $(self.name) anim dog_discipline; $(self.name).animsave = 4 wait 3 $(self.name).scale = 0.001 $(self.name).angles = $(self.name).angles + ( 0 180 0 ) waitframe $(self.name).scale = 1 $(self.name) triggerable $(self.name).animsave = 1 self.shot = 0 self.runonce = 0 $(self.name) thread dog_anims } end biteplayers: for(local.i = 1; local.i <= $player.size; local.i++) { if(vector_length(self.origin - $player[local.i].origin) < 70) // ideally place the dog in the corner of a map, so the dog can face players { // when they're red and angry. if(isalive $player[local.i]) { $player[local.i] iprint ("Don't get too close to an angry dog.") $player[local.i] thread bite_anim self.name } waitframe // future edit: make dog's angles always face the nearest player when angry. Doing "$(self.name) lookat $player[local.i]" } // did not work, since "lookat" is reserved for AI actors. } end bite_anim local.name: $(local.name).bitingplayer = 1 $(local.name) anim dog_bite_face killent self.entnum // "self kill" doesn't work if the player just respawned wait 1 $(local.name) anim dog_stand_curious $(local.name).bitingplayer = 0 end //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// player: self nottriggerable local.player = parm.other if(local.player.isdog == 1) { self triggerable local.player iprint ("You are already a dog.") end } //local.player iprint ("Bite people to kill them. CAUTION: This includes teammates.") local.player iprint ("FIRE = bite, USE + FIRE = bark, WALK + Stand = quiet walking.") //local.player iprint ("JUMP = high jump animation, hold USE + JUMP = shorter jump.") local.player.isdog = 1 local.player thread test local.specorg = local.player.origin local.specang = (angles_toforward local.player.viewangles) local.anim = spawn script_model model self.model local.anim.angles = local.player.angles local.anim anim idle local.anim notsolid local.player takeall local.player hide local.player thread get_movement local.player thread run_counter local.pos = local.anim gettagposition "tag_mouth" // when the player bites, anyone who touches the dog's mouth is killed. local.anim.trigger = spawn trigger_multiple local.anim.trigger.origin = local.pos local.anim.trigger setsize ( -5 -5 -5 ) ( 5 5 5 ) local.anim.trigger setthread bite local.anim.trigger nottriggerable local.anim.trigger.player = local.player local.anim.trigger glue local.anim local.anim.origin = (local.specorg + ((local.specang[0]) (local.specang[1]) (0)) * 50) local.player.dog = local.anim local.anim thread move local.player self triggerable end bite: local.player = parm.other if(local.player == self.player || local.player.bitten == 1) { end } else { local.player.bitten = 1 local.player hurt 9999 wait 1 local.player.bitten = 0 } end run_counter: local.c = 0 local.team = self.dmteam while(1) { if(self == NULL || self.dmteam != local.team || !isalive self) { self.isdog = 0; end } local.position = self getposition while(self.dog_anim == dog_run && local.position == standing) // count to 5 seconds when dog begins running, only if player is standing. { wait 0.1 if(local.c < 50) { local.c++ } if(local.c >= 50) { self.runningstop = 1 } // when the player runs for 5+ seconds and stops running afterwards, do the "dog_leash_stop" animation. } if(self.dog_anim != dog_run) { self.runningstop = 0; local.c = 0 } waitframe } end move local.player: local.anim = dog_stand_idle local.team = local.player.dmteam while(1) { if(local.player == NULL || local.player.dmteam != local.team) { local.r = randomint(4) if(local.r == 0) { self anim death } if(local.r == 1) { self anim dog_death } if(local.r == 2) { self anim dog_death2 } if(local.r == 3) { self anim dog_death_run } // if they switch teams without dying, don't let them respawn empty handed. if(isalive local.player && local.player.dmteam != "axis") { local.player give models/weapons/colt45.tik; local.player give models/weapons/m2frag_grenade.tik; local.player give models/weapons/bar.tik } if(isalive local.player && local.player.dmteam == "axis") { local.player give models/weapons/p38.tik; local.player give models/weapons/steilhandgranate.tik; local.player give models/weapons/mp44.tik } wait 10 self remove end } local.specang = (angles_toforward local.player.viewangles) local.specorg = local.player.origin self.velocity = local.player.velocity self.origin = (local.specorg + ((local.specang[0]) (local.specang[1]) (0)) * 50) // keep dog 50 units in front of player self.angles = local.player.angles if(local.anim != local.player.dog_anim) { if(local.player.dog_anim == dog_death) { local.r = randomint(4) if(local.r == 0) { self anim death } if(local.r == 1) { self anim dog_death } if(local.r == 2) { self anim dog_death2 } if(local.r == 3) { self anim dog_death_run } wait 10 self remove end } self anim local.player.dog_anim local.anim = local.player.dog_anim // perform the current dog_anim anim, then update local.anim if the player is still alive. } waitframe } end get_movement: local.team = self.dmteam while(1) { if(self == NULL || self.dmteam != local.team) { self.isdog = 0; end } else { if(self.health < local.health && local.position != offground) // if the dog takes damage (not fall damage), then do a pain animation. { local.r = randomint(3) if(local.r == 0) { self.dog_anim = dog_pain_head } if(local.r == 1) { self.dog_anim = dog_pain_front } if(local.r == 2) { self.dog_anim = dog_pain_back } wait 0.5 } local.health = self.health local.position = self getposition // these are found in global/mike_legs.st (moveposflags "movement" "position") local.movement = self getmovement // for some reason when walking while standing (not crouching), movement = "standing" (should be "walking", possible game bug). if(self.origin == local.originold && self.runningstop == 1) // if the dog is running for 5 seconds or more, { // do "dog_leash_stop" when dog stops running. self.dog_anim = dog_leash_stop self.runningstop = 0 wait 0.5 } if(local.movement == running) { self.dog_anim = dog_run } if(local.movement == walking) { self.dog_anim = dog_walk_bored } // this only works for crouching + walking. if(local.movement == standing && self.origin != local.originold) { self.dog_anim = dog_walk_leash } // fix for standing + walking. also move around silently. if(local.position == standing && local.movement == standing && self.origin == local.originold) { self.dog_anim = dog_stand_idle } // "if dog_rest, then dog_standup, wait 0.3, dog_stand_idle" was local.originold = self.origin // removed from here, since "standup" anim didn't work well with players. if(local.position == offground && self.dog_anim == dog_run) { self.dog_anim = dog_leap } // dog jumps higher than before with only the "leap" anim. if(self.useheld == 1) { if(local.position == offground && self.dog_anim == dog_leap) { self.dog_anim = dog_land } // if holding USE, the dog will not jump as high since "land" anim is added. } if(local.position == crouching && local.movement == standing) { waitframe // keeps the dog_rest anim timed properly. waitframe waitframe waitframe local.position = self getposition if(local.position == offground) { self.dog_anim = dog_leap } // crouching, but still falls. else if(local.position == crouching && local.movement == standing) { self.dog_anim = dog_rest } } if!(isalive self) { self.dog_anim = dog_death self scale 0 while!(isalive self) { if(self == NULL || self.dmteam != local.team) { self.isdog = 0; end } else { waitframe } } self scale 1 self.isdog = 0 end } if(self.fireheld == 1 && self.useheld == 0 && self.held != 1) { self.held = 1 if(self.viewangles[0] < 0 || self.viewangles[0] >= 180) // if player is looking horizontally to straight up, bite face { // if player is looking horizontally to straight down, bite leg self.dog.trigger triggerable self.dog_anim = dog_bite_face wait .75 self.dog.trigger nottriggerable } else { self.dog.trigger triggerable self.dog_anim = dog_bite_leg wait .75 self.dog.trigger nottriggerable } } if(self.fireheld == 1 && self.useheld == 1 && self.held2 != 1) // if player is Left/Right-clicking while holding USE, only bark. { self.held2 = 1 self.dog_anim = dog_bark wait .20 } if(self.fireheld != 1 || self.useheld != 1) { self.held = 0; self.held2 = 0 } } waitframe self takeall // in case they pick up some weapons } end