123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /// <reference path="../Thing.ts" />
- /// <reference path="../AI.ts" />
- /// <reference path="Person/Attribute.ts" />
- /// <reference path="Person/Skill.ts" />
- /// <reference path="../Container/Corpse.ts" />
- /**
- * A person is a thing that happens to be "alive" in some significant way, not necessarily human.
- * A robot is a person.
- * A dog is a person.
- *
- * Fuck your standards.
- */
- enum PersonStance {
- STANDING, ALLFOURS, KNOCKEDOUT
- }
- let PersonStanceNames = {};
- PersonStanceNames[PersonStance.STANDING] = "standing";
- PersonStanceNames[PersonStance.ALLFOURS] = "kneeling";
- PersonStanceNames[PersonStance.KNOCKEDOUT] = "passed out";
- class Person extends Thing implements AttributeBearer, SkillBearer {
- public AI = new AI({actor: this});
- public animated = true;
- public soreness = 0;
- public lastHealthUpdate = 0;
- public stamina = 10;
- public lastStaminaUpdate = 0;
- public staminaPerTurn = 1;
- public static MAX_STAMINA = 10;
- public static STRENGTH_SORENESS_MULTIPLIER = 4;
- public stance : PersonStance = PersonStance.STANDING;
- public reputation : number = 0;
- public constructor (options : ThingOptions) {
- super(options);
- this.addGetAlterations((person : Person) => {
- // Let's not do this for NPCs. It can break patches.
- if (person.isPlayer()) {
- return {
- Stats: this.attributeValue,
- Skills: this.skillValue
- }
- } else {
- return {
- reputation : this.reputation
- }
- }
- });
- // We *should* have the bodypart thing here, but there are issues with Humanoids and that...
- // this.addGetAlterations((person : Person) => {
- //
- // });
- this.addSetAlterations((person : Person, changes) => {
- // Let's not do this for NPCs. It can break patches.
- if (person.isPlayer()) {
- if (changes.Stats != undefined) {
- for (let name in changes.Stats) {
- let attr = Attribute.getAttribute(name);
- if (attr != undefined) {
- this.setStat(attr, changes.Stats[name]);
- }
- }
- }
- if (changes.Skills != undefined) {
- for (let name in changes.Skills) {
- let attr = Skill.getSkill(name);
- if (attr != undefined) {
- this.setSkill(attr, changes.Skills[name]);
- }
- }
- }
- } else {
- if (changes.reputation != undefined) {
- this.reputation = changes.reputation;
- }
- }
- });
- }
- public changeHealth (n : number) {
- let bodyparts = <Array<Bodypart>> this.getParts(Bodypart);
- for (let i = 0; i < bodyparts.length; i++) {
- bodyparts[i].changeSoreness(n);
- }
- this.updateHealth();
- }
- /**
- * Returns health as a number from 0 to 10.
- */
- public getHealthOnScale () {
- return Math.ceil(10 - (this.getHealth() * 10));
- }
- /**
- * Returns current health.
- * Important = force update, otherwise use sufficiently accurate current value. to prevent looping too much.
- * @param {boolean} important
- * @returns {number}
- */
- public getHealth (important? : boolean) {
- if (important === true || this.lastHealthUpdate != WorldState.getCurrentTurn()) {
- this.updateHealth();
- }
- return this.soreness / this.getMaxHealth()
- }
- public getMaxHealth () {
- return (this.getStat(Attributes.Strength) * Person.STRENGTH_SORENESS_MULTIPLIER);
- }
- /**
- * Lazy updates allow us to count Health/Stamina for NPCs without overloading the Every Turn rulebook.
- */
- public updateHealth () {
- let health = 0;
- let bodyparts = this.getParts(Bodypart);
- for (let i = 0; i < bodyparts.length; i++) {
- health += bodyparts[i].getWeightedSoreness();
- }
- this.soreness = health;
- this.lastHealthUpdate = WorldState.getCurrentTurn();
- }
- public changeStamina (n : number) {
- this.updateStamina();
- this.stamina += n;
- if (this.stamina > Person.MAX_STAMINA) {
- this.stamina = Person.MAX_STAMINA;
- } else if (this.stamina < 0) {
- this.stamina = 0;
- }
- }
- /**
- * Returns stamina as a number from 0 to 10.
- */
- public getStaminaOnScale () {
- return Math.round(
- ((this.stamina * 10) / Person.MAX_STAMINA)
- );
- }
- public updateStamina () {
- var nTurns = WorldState.getCurrentTurn() - this.lastStaminaUpdate;
- this.stamina += this.staminaPerTurn * nTurns;
- if (this.stamina > Person.MAX_STAMINA) {
- this.stamina = Person.MAX_STAMINA;
- }
- }
- public isPlayer () {
- return (<any> this) == WorldState.player;
- }
- protected attributeValue : {[id : string] : number} = {};
- protected skillValue : {[id : string] : number} = {};
- public getStat (stat : Attribute) {
- if (this.attributeValue[stat.id] == undefined) {
- this.attributeValue[stat.id] = stat.defaultValue;
- }
- return this.attributeValue[stat.id];
- }
- public setStat (stat : Attribute, value : number) {
- this.attributeValue[stat.id] = value;
- }
- public getSkill (stat : Skill) {
- if (this.skillValue[stat.id] == undefined) {
- this.skillValue[stat.id] = stat.defaultValue;
- }
- return this.skillValue[stat.id];
- }
- public setSkill (stat : Skill, value : number) {
- this.skillValue[stat.id] = value;
- }
- public die () {
- let corpse = new Corpse({
- name : this.name + "'s corpse",
- unique : false,
- description : new Say("The lifeless body of ", this, ". May ", new SayHeSheIt(this), " rest in peace.")
- });
- corpse.put(...Thing.CarryRelation.getRight(this));
- corpse.put(...Thing.WearRelation.getRight(this));
- this.getRoom().place(corpse);
- OutOfPlay.removeFromPlay(this);
- }
- }
|