diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cr.hh | 17 | ||||
| -rw-r--r-- | src/crmain.cc | 456 | ||||
| -rw-r--r-- | src/crskill.cc | 70 | ||||
| -rw-r--r-- | src/enums.hh | 4 | ||||
| -rw-r--r-- | src/objects.cc | 3 | ||||
| -rw-r--r-- | src/stubs.hh | 7 |
6 files changed, 536 insertions, 21 deletions
@@ -16,6 +16,7 @@ struct TOutfit{ union{ uint16 ObjectType; uint8 Colors[4]; + uint32 PackedData; }; }; @@ -742,6 +743,22 @@ void ExitKillStatistics(void); bool IsRaceValid(int Race); int GetRaceByName(const char *RaceName); +const char *GetRaceName(int Race); +TOutfit GetRaceOutfit(int Race); +bool GetRaceNoSummon(int Race); +bool GetRaceNoConvince(int Race); +bool GetRaceNoIllusion(int Race); +bool GetRaceNoParalyze(int Race); +int GetRaceSummonCost(int Race); +int GetRacePoison(int Race); +bool GetRaceUnpushable(int Race); + +TOutfit ReadOutfit(TReadScriptFile *Script); +void WriteOutfit(TReadScriptFile *Script, TOutfit Outfit); + +// crskill.cc +// ============================================================================= +int GetSkillByName(const char *Name); // crnonpl.cc // ============================================================================= diff --git a/src/crmain.cc b/src/crmain.cc index 6a9602d..48d31be 100644 --- a/src/crmain.cc +++ b/src/crmain.cc @@ -1239,7 +1239,461 @@ int GetRaceByName(const char *RaceName){ return Result; } -void LoadRaces(void); //TODO +const char *GetRaceName(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceName: Ungültige Rassen-Nummer %d.\n", Race); + return NULL; + } + + return RaceData[Race].Name; +} + +TOutfit GetRaceOutfit(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceOutfit: Ungültige Rassen-Nummer %d.\n", Race); + return RaceData[1].Outfit; + } + + return RaceData[Race].Outfit; +} + +bool GetRaceNoSummon(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceNoSummon: Ungültige Rassen-Nummer %d.\n", Race); + return true; + } + + return RaceData[Race].NoSummon; +} + +bool GetRaceNoConvince(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceNoConvince: Ungültige Rassen-Nummer %d.\n", Race); + return true; + } + + return RaceData[Race].NoConvince; +} + +bool GetRaceNoIllusion(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceNoIllusion: Ungültige Rassen-Nummer %d.\n", Race); + return true; + } + + return RaceData[Race].NoIllusion; +} + +bool GetRaceNoParalyze(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceNoParalyze: Ungültige Rassen-Nummer %d.\n", Race); + return true; + } + + return RaceData[Race].NoParalyze; +} + +int GetRaceSummonCost(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceSummonCost: Ungültige Rassen-Nummer %d.\n", Race); + return 0; + } + + return RaceData[Race].SummonCost; +} + +int GetRacePoison(int Race){ + if(!IsRaceValid(Race)){ + error("GetRacePoison: Ungültige Rassen-Nummer %d.\n", Race); + return 0; + } + + return RaceData[Race].Poison; +} + +bool GetRaceUnpushable(int Race){ + if(!IsRaceValid(Race)){ + error("GetRaceUnpushable: Ungültige Rassen-Nummer %d.\n", Race); + return true; + } + + return RaceData[Race].Unpushable; +} + +// TODO(fusion): Probably move this somewhere else? +TOutfit ReadOutfit(TReadScriptFile *Script){ + TOutfit Outfit = {}; + Script->readSymbol('('); + Outfit.OutfitID = Script->readNumber(); + Script->readSymbol(','); + if(Outfit.OutfitID == 0){ + Outfit.ObjectType = (uint16)Script->readNumber(); + }else{ + memcpy(Outfit.Colors, Script->readBytesequence(), sizeof(Outfit.Colors)); + } + Script->readSymbol(')'); +} + +// TODO(fusion): Probably move this somewhere else? +void WriteOutfit(TReadScriptFile *Script, TOutfit Outfit){ + Script->writeText("("); + Script->writeNumber(Outfit.OutfitID); + Script->writeText(","); + if(Outfit.OutfitID == 0){ + Script->writeNumber((int)Outfit.ObjectType); + }else{ + Script->writeBytesequence(Outfit.Colors, sizeof(Outfit.Colors)); + } + Script->writeText(")"); +} + +void LoadRace(const char *FileName){ + TReadScriptFile Script; + + Script.open(FileName); + + // NOTE(fusion): It seems we expect `RaceNumber` to be the first attribute + // declared in a race file. + if(strcmp(Script.readIdentifier(), "racenumber") != 0){ + Script.error("race number expected"); + } + + Script.readSymbol('='); + + int RaceNumber = Script.readNumber(); + if(!IsRaceValid(Race)){ + Script.error("illegal race number"); + } + + TRaceData *Race = &RaceData[RaceNumber]; + if(Race->Name[0] != 0){ + Script.error("race already defined"); + } + + Race->Outfit = TOutfit{}; + Race->Outfit.OutfitID = RaceNumber; + + while(true){ + Script.nextToken(); + if(Script.Token == ENDOFFILE){ + Script.close(); + break; + } + + char Identifier[MAX_IDENT_LENGTH]; + strcpy(Identifier, Script.getIdentifier()); + Script.readSymbol('='); + + if(strcmp(Identifier, "name") == 0){ + strcpy(Race->Name, Script.readString()); + }else if(strcmp(Identifier, "article") == 0){ + strcpy(Race->Article, Script.readString()); + }else if(strcmp(Identifier, "outfit") == 0){ + Race->Outfit = ReadOutfit(Script); + }else if(strcmp(Identifier, "corpse") == 0){ + int CorpseTypeID = Script.readNumber(); + Race->MaleCorpse = CorpseTypeID; + Race->FemaleCorpse = CorpseTypeID; + }else if(strcmp(Identifier, "corpses") == 0){ + Race->MaleCorpse = Script.readNumber(); + Script.readSymbol(','); + Race->FemaleCorpse = Script.readNumber(); + }else if(strcmp(Identifier, "blood") == 0){ + const char *Blood = Script.readIdentifier(); + if(strcmp(Blood, "blood") == 0){ + Race->Blood = BT_BLOOD; + }else if(strcmp(Blood, "slime") == 0){ + Race->Blood = BT_SLIME; + }else if(strcmp(Blood, "bones") == 0){ + Race->Blood = BT_BONES; + }else if(strcmp(Blood, "fire") == 0){ + Race->Blood = BT_FIRE; + }else if(strcmp(Blood, "energy") == 0){ + Race->Blood = BT_ENERGY; + }else{ + Script.error("unknown blood type"); + } + }else if(strcmp(Identifier, "experience") == 0){ + Race->ExperiencePoints = Script.readNumber(); + }else if(strcmp(Identifier, "summoncost") == 0){ + Race->SummonCost = Script.readNumber(); + }else if(strcmp(Identifier, "fleethreshold") == 0){ + Race->FleeThreshold = Script.readNumber(); + }else if(strcmp(Identifier, "attack") == 0){ + Race->Attack = Script.readNumber(); + }else if(strcmp(Identifier, "defend") == 0){ + Race->Defend = Script.readNumber(); + }else if(strcmp(Identifier, "armor") == 0){ + Race->Armor = Script.readNumber(); + }else if(strcmp(Identifier, "poison") == 0){ + Race->Poison = Script.readNumber(); + }else if(strcmp(Identifier, "losetarget") == 0){ + Race->LoseTarget = Script.readNumber(); + }else if(strcmp(Identifier, "strategy") == 0){ + Script.readSymbol('('); + Race->Strategy[0] = Script.readNumber(); + Script.readSymbol(','); + Race->Strategy[1] = Script.readNumber(); + Script.readSymbol(','); + Race->Strategy[2] = Script.readNumber(); + Script.readSymbol(','); + Race->Strategy[3] = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(Identifier, "flags") == 0){ + Script.readSymbol('{'); + do{ + const char *Flag = Script.getIdentifier(); + if(strcmp(Flag, "kickboxes") == 0){ + Race->KickBoxes = true; + }else if(strcmp(Flag, "kickcreatures") == 0){ + Race->KickCreatures = true; + }else if(strcmp(Flag, "seeinvisible") == 0){ + Race->SeeInvisible = true; + }else if(strcmp(Flag, "unpushable") == 0){ + Race->Unpushable = true; + }else if(strcmp(Flag, "distancefighting") == 0){ + Race->DistanceFighting = true; + }else if(strcmp(Flag, "nosummon") == 0){ + Race->NoSummon = true; + }else if(strcmp(Flag, "noconvince") == 0){ + Race->NoConvince = true; + }else if(strcmp(Flag, "noillusion") == 0){ + Race->NoIllusion = true; + }else if(strcmp(Flag, "noburning") == 0){ + Race->NoBurning = true; + }else if(strcmp(Flag, "nopoison") == 0){ + Race->NoPoison = true; + }else if(strcmp(Flag, "noenergy") == 0){ + Race->NoEnergy = true; + }else if(strcmp(Flag, "nohit") == 0){ + Race->NoHit = true; + }else if(strcmp(Flag, "nolifedrain") == 0){ + Race->NoLifeDrain = true; + }else if(strcmp(Flag, "noparalyze") == 0){ + Race->NoParalyze = true; + }else{ + Script.error("unknown flag"); + } + }while(Script.readSpecial() != '}'); + }else if(strcmp(Identifier, "skills") == 0){ + Script.readSymbol('{'); + do{ + Script.readSymbol('('); + int SkillNr = GetSkillByName(Script.readIdentifier()); + if(SkillNr == -1){ + Script.error("unknown skill name"); + } + + // NOTE(fusion): Skills are indexed from 1. + Race->Skills += 1; + TSkillData *SkillData = Race->Skill.at(Race->Skills); + SkillData->Nr = SkillNr; + Script.readSymbol(','); + SkillData->Actual = Script.readNumber(); + Script.readSymbol(','); + SkillData->Minimum = Script.readNumber(); + Script.readSymbol(','); + SkillData->Maximum = Script.readNumber(); + Script.readSymbol(','); + SkillData->NextLevel = Script.readNumber(); + Script.readSymbol(','); + SkillData->FactorPercent = Script.readNumber(); + Script.readSymbol(','); + SkillData->AddLevel = Script.readNumber(); + Script.readSymbol(')'); + }while(Script.readSpecial() != '}'); + }else if(strcmp(Identifier, "talk") == 0){ + Script.readSymbol('{'); + do{ + // NOTE(fusion): Talks are indexed from 1. + Race->Talks += 1; + *Race->Talk.at(Race->Talks) = AddDynamicString(Script.readString()); + }while(Script.readSpecial() != '}'); + }else if(strcmp(Identifier, "inventory") == 0){ + Script.readSymbol('{'); + do{ + Script.readSymbol('('); + // NOTE(fusion): Items are indexed from 1. + Race->Items += 1; + TItemData *ItemData = Race->Item.at(Race->Items); + ItemData->Type = Script.readNumber(); + Script.readSymbol(','); + ItemData->Maximum = Script.readNumber(); + Script.readSymbol(','); + ItemData->Probability = Script.readNumber(); + Script.readSymbol(')'); + }while(Script.readSpecial() != '}'); + }else if(strcmp(Identifier, "spells") == 0){ + Script.readSymbol('{'); + do{ + Race->Spells += 1; + TSpellData *SpellData = Race->Spell.at(Race->Spells); + + // NOTE(fusion): Spell shape. + { + const char *SpellShape = Script.readIdentifier(); + if(strcmp(SpellShape, "actor") == 0){ + SpellData->Shape = SHAPE_ACTOR; + Script.readSymbol('('); + SpellData->ShapeParam1 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellShape, "victim") == 0){ + SpellData->Shape = SHAPE_VICTIM; + Script.readSymbol('('); + SpellData->ShapeParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam3 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellShape, "origin") == 0){ + SpellData->Shape = SHAPE_ORIGIN; + Script.readSymbol('('); + SpellData->ShapeParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam2 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellShape, "destination") == 0){ + SpellData->Shape = SHAPE_DESTINATION; + Script.readSymbol('('); + SpellData->ShapeParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam3 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam4 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellShape, "angle") == 0){ + SpellData->Shape = SHAPE_ANGLE; + Script.readSymbol('('); + SpellData->ShapeParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ShapeParam3 = Script.readNumber(); + Script.readSymbol(')'); + }else{ + Script.error("unknown spell shape"); + } + } + + Script.readSymbol('I'); + + // NOTE(fusion): Spell impact. + { + const char *SpellImpact = Script.readIdentifier(); + if(strcmp(SpellImpact, "damage") == 0){ + SpellData->Impact = IMPACT_DAMAGE; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam3 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "field") == 0){ + SpellData->Impact = IMPACT_FIELD; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "healing") == 0){ + SpellData->Impact = IMPACT_HEALING; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam2 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "speed") == 0){ + SpellData->Impact = IMPACT_SPEED; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam3 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "drunken") == 0){ + SpellData->Impact = IMPACT_DRUNKEN; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam3 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "strength") == 0){ + SpellData->Impact = IMPACT_STRENGTH; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam2 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam3 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam4 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "outfit") == 0){ + SpellData->Impact = IMPACT_OUTFIT; + Script.readSymbol('('); + TOutfit Outfit = ReadOutfit(Script); + SpellData->ImpactParam1 = Outfit.OutfitID; + SpellData->ImpactParam2 = (int)Outfit.PackedData; + Script.readSymbol(','); + SpellData->ImpactParam3 = Script.readNumber(); + Script.readSymbol(')'); + }else if(strcmp(SpellImpact, "summon") == 0){ + SpellData->Impact = IMPACT_SUMMON; + Script.readSymbol('('); + SpellData->ImpactParam1 = Script.readNumber(); + Script.readSymbol(','); + SpellData->ImpactParam2 = Script.readNumber(); + Script.readSymbol(')'); + }else{ + Script.error("unknown spell impact"); + } + } + + Script.readSymbol(':'); + + // NOTE(fusion): Spell delay. + { + SpellData->Delay = Script.readNumber(); + if(SpellData->Delay == 0){ + Script.error("zero spell delay"); + } + } + }while(Script.readSpecial() != '}'); + }else{ + Script.error("unknown race field"); + } + } +} + +void LoadRaces(void){ + // TODO(fusion): It is possible to leak `MonsterDir` if `LoadRace` throws on + // errors (which it does). This is usually not a problem because failing here + // means we're cascading back to `InitAll` which will report the error and + // exit, but it is something to keep in mind for any functions that uses + // exceptions with non-RAII resources. + + DIR *MonsterDir = opendir(MONSTERPATH); + if(MonsterDir == NULL){ + error("LoadRaces: Unterverzeichnis %s nicht gefunden\n", MONSTERPATH); + throw "Cannot load races"; + } + + char FilePath[4096]; + while(dirent *DirEntry = readdir(MonsterDir)){ + const char *FileExt = findLast(DirEntry->d_name, '.'); + if(FileExt != NULL && strcmp(FileExt, ".mon") == 0){ + snprintf(FilePath, sizeof(FilePath), "%s/%s", MONSTERPATH, DirEntry->d_name); + LoadRace(FilePath); + } + } + + closedir(MonsterDir); +} // Monster Raid // ============================================================================= diff --git a/src/crskill.cc b/src/crskill.cc index 8e259a8..84402ee 100644 --- a/src/crskill.cc +++ b/src/crskill.cc @@ -345,10 +345,10 @@ bool TSkillLevel::Jump(int Range){ return false; } - this->Master->Skills[SKILL_HITPOINTS ]->Advance(Range); - this->Master->Skills[SKILL_MANA ]->Advance(Range); - this->Master->Skills[SKILL_GO_STRENGTH ]->Advance(Range); - this->Master->Skills[SKILL_CARRY_WEIGHT]->Advance(Range); + this->Master->Skills[SKILL_HITPOINTS ]->Advance(Range); + this->Master->Skills[SKILL_MANA ]->Advance(Range); + this->Master->Skills[SKILL_GO_STRENGTH ]->Advance(Range); + this->Master->Skills[SKILL_CARRY_STRENGTH]->Advance(Range); AnnounceChangedCreature(this->Master->ID, 4); this->Master->Combat.CheckCombatValues(); @@ -1142,7 +1142,7 @@ bool TSkillBase::NewSkill(uint16 SkillNo, TCreature *Creature){ case SKILL_HITPOINTS: Skill = new TSkillHitpoints(SkillNo, Creature); break; case SKILL_MANA: Skill = new TSkillMana(SkillNo, Creature); break; case SKILL_GO_STRENGTH: Skill = new TSkillGoStrength(SkillNo, Creature); break; - case SKILL_CARRY_WEIGHT: Skill = new TSkillCarryStrength(SkillNo, Creature); break; + case SKILL_CARRY_STRENGTH: Skill = new TSkillCarryStrength(SkillNo, Creature); break; case SKILL_FED: Skill = new TSkillFed(SkillNo, Creature); break; case SKILL_LIGHT: Skill = new TSkillLight(SkillNo, Creature); break; case SKILL_ILLUSION: Skill = new TSkillIllusion(SkillNo, Creature); break; @@ -1164,10 +1164,8 @@ bool TSkillBase::SetSkills(int Race){ return false; } - // TODO(fusion): This is referencing some global table with probably all - // types of creatures. - int NumSkills = RaceData[Race].Skills; - for(int i = 0; i < NumSkills; i += 1){ + // NOTE(fusion): Skills are indexed from 1. + for(int i = 1; i <= RaceData[Race].Skills; i += 1){ TSkillData *SkillData = RaceData[Race].Skill.at(i); // BUG(fusion): We don't check if `Skill` is valid? Could be NULL. We @@ -1251,6 +1249,60 @@ void TSkillBase::DelTimer(uint16 SkNr){ } } +// Helpers +//============================================================================== +int GetSkillByName(const char *Name){ + int Result = -1; + if(strcmp(Name, "level") == 0){ + Result = SKILL_LEVEL; + }else if(strcmp(Name, "magiclevel") == 0){ + Result = SKILL_MAGIC_LEVEL; + }else if(strcmp(Name, "hitpoints") == 0){ + Result = SKILL_HITPOINTS; + }else if(strcmp(Name, "mana") == 0){ + Result = SKILL_MANA; + }else if(strcmp(Name, "gostrength") == 0){ + Result = SKILL_GO_STRENGTH; + }else if(strcmp(Name, "carrystrength") == 0){ + Result = SKILL_CARRY_STRENGTH; + }else if(strcmp(Name, "shielding") == 0){ + Result = SKILL_SHIELDING; + }else if(strcmp(Name, "distancefighting") == 0){ + Result = SKILL_DISTANCE; + }else if(strcmp(Name, "swordfighting") == 0){ + Result = SKILL_SWORD; + }else if(strcmp(Name, "clubfighting") == 0){ + Result = SKILL_CLUB; + }else if(strcmp(Name, "axefighting") == 0){ + Result = SKILL_AXE; + }else if(strcmp(Name, "fistfighting") == 0){ + Result = SKILL_FIST; + }else if(strcmp(Name, "magicdefense") == 0){ + Result = SKILL_MAGIC_DEFENSE; + }else if(strcmp(Name, "fishing") == 0){ + Result = SKILL_FISHING; + }else if(strcmp(Name, "eating") == 0){ + Result = SKILL_FED; + }else if(strcmp(Name, "shining") == 0){ + Result = SKILL_LIGHT; + }else if(strcmp(Name, "illusion") == 0){ + Result = SKILL_ILLUSION; + }else if(strcmp(Name, "poison") == 0){ + Result = SKILL_POISON; + }else if(strcmp(Name, "burning") == 0){ + Result = SKILL_BURNING; + }else if(strcmp(Name, "energy") == 0){ + Result = SKILL_ENERGY; + }else if(strcmp(Name, "drunken") == 0){ + Result = SKILL_DRUNK; + }else if(strcmp(Name, "manashield") == 0){ + Result = SKILL_MANASHIELD; + }else if(strcmp(Name, "soulpoints") == 0){ + Result = SKILL_SOUL; + } + return Result; +} + // Initialization //============================================================================== void InitCrskill(void){ diff --git a/src/enums.hh b/src/enums.hh index 8257677..4801e49 100644 --- a/src/enums.hh +++ b/src/enums.hh @@ -415,14 +415,14 @@ enum Skill: int { SKILL_HITPOINTS = 2, SKILL_MANA = 3, SKILL_GO_STRENGTH = 4, // speed? - SKILL_CARRY_WEIGHT = 5, // capacity? + SKILL_CARRY_STRENGTH = 5, // capacity? SKILL_SHIELDING = 6, SKILL_DISTANCE = 7, SKILL_SWORD = 8, SKILL_CLUB = 9, SKILL_AXE = 10, SKILL_FIST = 11, - // 12? + SKILL_MAGIC_DEFENSE = 12, SKILL_FISHING = 13, SKILL_FED = 14, SKILL_LIGHT = 15, diff --git a/src/objects.cc b/src/objects.cc index f617fb9..51171f0 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -576,8 +576,7 @@ static void LoadObjects(void){ } } }else{ - // TODO(fusion): - // error("Invalid object type field \"%s\"", Identifier); + Script.error("Unknown object type field"); } } } diff --git a/src/stubs.hh b/src/stubs.hh index ba87f27..3495a59 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -40,13 +40,6 @@ extern TConnection *GetNextConnection(void); extern const char *GetName(Object Obj); extern Object GetObject(uint32 CreatureID, int x, int y, int z, int RNum, ObjectType Type); extern TPlayer *GetPlayer(uint32 CreatureID); -extern bool GetRaceNoConvince(int Race); -extern bool GetRaceNoIllusion(int Race); -extern bool GetRaceNoParalyze(int Race); -extern bool GetRaceNoSummon(int Race); -extern TOutfit GetRaceOutfit(int Race); -extern int GetRacePoison(int Race); -extern int GetRaceSummonCost(int Race); extern void GraphicalEffect(int x, int y, int z, int Type); extern void GraphicalEffect(Object Obj, int Type); extern int IdentifyPlayer(const char *Name, bool ExactMatch, bool IgnoreGamemasters, TPlayer **Player); |
